From 4fd80ff6bc7bb2f31671164aaa86b701f39023db Mon Sep 17 00:00:00 2001 From: amantley Date: Tue, 8 Jan 2019 15:26:46 -0800 Subject: [PATCH 001/112] implementing the spline ik for the spline as an anim node --- libraries/animation/src/AnimContext.h | 1 + libraries/animation/src/AnimNodeLoader.cpp | 22 +++++++ libraries/animation/src/AnimSplineIK.cpp | 77 ++++++++++++++++++++++ libraries/animation/src/AnimSplineIK.h | 76 +++++++++++++++++++++ 4 files changed, 176 insertions(+) create mode 100644 libraries/animation/src/AnimSplineIK.cpp create mode 100644 libraries/animation/src/AnimSplineIK.h diff --git a/libraries/animation/src/AnimContext.h b/libraries/animation/src/AnimContext.h index c455dd9c8f..e3ab5d9788 100644 --- a/libraries/animation/src/AnimContext.h +++ b/libraries/animation/src/AnimContext.h @@ -28,6 +28,7 @@ enum class AnimNodeType { InverseKinematics, DefaultPose, TwoBoneIK, + SplineIK, PoleVectorConstraint, NumTypes }; diff --git a/libraries/animation/src/AnimNodeLoader.cpp b/libraries/animation/src/AnimNodeLoader.cpp index dfa61e9fea..562a614b4a 100644 --- a/libraries/animation/src/AnimNodeLoader.cpp +++ b/libraries/animation/src/AnimNodeLoader.cpp @@ -26,6 +26,7 @@ #include "AnimInverseKinematics.h" #include "AnimDefaultPose.h" #include "AnimTwoBoneIK.h" +#include "AnimSplineIK.h" #include "AnimPoleVectorConstraint.h" using NodeLoaderFunc = AnimNode::Pointer (*)(const QJsonObject& jsonObj, const QString& id, const QUrl& jsonUrl); @@ -41,6 +42,7 @@ static AnimNode::Pointer loadManipulatorNode(const QJsonObject& jsonObj, const Q static AnimNode::Pointer loadInverseKinematicsNode(const QJsonObject& jsonObj, const QString& id, const QUrl& jsonUrl); static AnimNode::Pointer loadDefaultPoseNode(const QJsonObject& jsonObj, const QString& id, const QUrl& jsonUrl); static AnimNode::Pointer loadTwoBoneIKNode(const QJsonObject& jsonObj, const QString& id, const QUrl& jsonUrl); +static AnimNode::Pointer loadSplineIKNode(const QJsonObject& jsonObj, const QString& id, const QUrl& jsonUrl); static AnimNode::Pointer loadPoleVectorConstraintNode(const QJsonObject& jsonObj, const QString& id, const QUrl& jsonUrl); static const float ANIM_GRAPH_LOAD_PRIORITY = 10.0f; @@ -123,6 +125,7 @@ static NodeLoaderFunc animNodeTypeToLoaderFunc(AnimNode::Type type) { case AnimNode::Type::InverseKinematics: return loadInverseKinematicsNode; case AnimNode::Type::DefaultPose: return loadDefaultPoseNode; case AnimNode::Type::TwoBoneIK: return loadTwoBoneIKNode; + case AnimNode::Type::SplineIK: return loadSplineIKNode; case AnimNode::Type::PoleVectorConstraint: return loadPoleVectorConstraintNode; case AnimNode::Type::NumTypes: return nullptr; }; @@ -140,6 +143,7 @@ static NodeProcessFunc animNodeTypeToProcessFunc(AnimNode::Type type) { case AnimNode::Type::InverseKinematics: return processDoNothing; case AnimNode::Type::DefaultPose: return processDoNothing; case AnimNode::Type::TwoBoneIK: return processDoNothing; + case AnimNode::Type::SplineIK: return processDoNothing; case AnimNode::Type::PoleVectorConstraint: return processDoNothing; case AnimNode::Type::NumTypes: return nullptr; }; @@ -574,6 +578,24 @@ static AnimNode::Pointer loadDefaultPoseNode(const QJsonObject& jsonObj, const Q return node; } +static AnimNode::Pointer loadSplineIKNode(const QJsonObject& jsonObj, const QString& id, const QUrl& jsonUrl) { + READ_FLOAT(alpha, jsonObj, id, jsonUrl, nullptr); + READ_BOOL(enabled, jsonObj, id, jsonUrl, nullptr); + READ_FLOAT(interpDuration, jsonObj, id, jsonUrl, nullptr); + READ_STRING(baseJointName, jsonObj, id, jsonUrl, nullptr); + READ_STRING(tipJointName, jsonObj, id, jsonUrl, nullptr); + READ_STRING(alphaVar, jsonObj, id, jsonUrl, nullptr); + READ_STRING(enabledVar, jsonObj, id, jsonUrl, nullptr); + READ_STRING(endEffectorRotationVarVar, jsonObj, id, jsonUrl, nullptr); + READ_STRING(endEffectorPositionVarVar, jsonObj, id, jsonUrl, nullptr); + + auto node = std::make_shared(id, alpha, enabled, interpDuration, + baseJointName, tipJointName, + alphaVar, enabledVar, + endEffectorRotationVarVar, endEffectorPositionVarVar); + return node; +} + static AnimNode::Pointer loadTwoBoneIKNode(const QJsonObject& jsonObj, const QString& id, const QUrl& jsonUrl) { READ_FLOAT(alpha, jsonObj, id, jsonUrl, nullptr); READ_BOOL(enabled, jsonObj, id, jsonUrl, nullptr); diff --git a/libraries/animation/src/AnimSplineIK.cpp b/libraries/animation/src/AnimSplineIK.cpp new file mode 100644 index 0000000000..db6b6864b1 --- /dev/null +++ b/libraries/animation/src/AnimSplineIK.cpp @@ -0,0 +1,77 @@ +// +// AnimSplineIK.cpp +// +// Created by Angus Antley on 1/7/19. +// Copyright (c) 2019 High Fidelity, Inc. All rights reserved. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "AnimSplineIK.h" +#include "AnimationLogging.h" +#include "CubicHermiteSpline.h" +#include +#include "AnimUtil.h" + +AnimSplineIK::AnimSplineIK(const QString& id, float alpha, bool enabled, float interpDuration, + const QString& baseJointName, + const QString& tipJointName, + const QString& alphaVar, const QString& enabledVar, + const QString& endEffectorRotationVarVar, const QString& endEffectorPositionVarVar) : + AnimNode(AnimNode::Type::SplineIK, id), + _alpha(alpha), + _enabled(enabled), + _interpDuration(interpDuration), + _baseJointName(baseJointName), + _tipJointName(tipJointName), + _alphaVar(alphaVar), + _enabledVar(enabledVar), + _endEffectorRotationVarVar(endEffectorRotationVarVar), + _endEffectorPositionVarVar(endEffectorPositionVarVar), + _prevEndEffectorRotationVar(), + _prevEndEffectorPositionVar() { + +} + +AnimSplineIK::~AnimSplineIK() { + +} + +const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const AnimContext& context, float dt, AnimVariantMap& triggersOut) { + qCDebug(animation) << "evaluating the spline function"; + assert(_children.size() == 1); + if (_children.size() != 1) { + return _poses; + } + + // evalute underPoses + AnimPoseVec underPoses = _children[0]->evaluate(animVars, context, dt, triggersOut); + _poses = underPoses; + return _poses; +} + +void AnimSplineIK::lookUpIndices() { + assert(_skeleton); + + // look up bone indices by name + std::vector indices = _skeleton->lookUpJointIndices({ _baseJointName, _tipJointName }); + + // cache the results + _baseJointIndex = indices[0]; + _tipJointIndex = indices[1]; + + if (_baseJointIndex != -1) { + _baseParentJointIndex = _skeleton->getParentIndex(_baseJointIndex); + } +} + +// for AnimDebugDraw rendering +const AnimPoseVec& AnimSplineIK::getPosesInternal() const { + return _poses; +} + +void AnimSplineIK::setSkeletonInternal(AnimSkeleton::ConstPointer skeleton) { + AnimNode::setSkeletonInternal(skeleton); + lookUpIndices(); +} \ No newline at end of file diff --git a/libraries/animation/src/AnimSplineIK.h b/libraries/animation/src/AnimSplineIK.h new file mode 100644 index 0000000000..36a29971a0 --- /dev/null +++ b/libraries/animation/src/AnimSplineIK.h @@ -0,0 +1,76 @@ +// +// AnimSplineIK.h +// +// Created by Angus Antley on 1/7/19. +// Copyright (c) 2019 High Fidelity, Inc. All rights reserved. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_AnimSplineIK_h +#define hifi_AnimSplineIK_h + +#include "AnimNode.h" +#include "AnimChain.h" + +// Spline IK for the spine +class AnimSplineIK : public AnimNode { +public: + AnimSplineIK(const QString& id, float alpha, bool enabled, float interpDuration, + const QString& baseJointName, const QString& tipJointName, + const QString& alphaVar, const QString& enabledVar, + const QString& endEffectorRotationVarVar, const QString& endEffectorPositionVarVar); + + virtual ~AnimSplineIK() override; + virtual const AnimPoseVec& evaluate(const AnimVariantMap& animVars, const AnimContext& context, float dt, AnimVariantMap& triggersOut) override; + +protected: + + enum class InterpType { + None = 0, + SnapshotToUnderPoses, + SnapshotToSolve, + NumTypes + }; + + // for AnimDebugDraw rendering + virtual const AnimPoseVec& getPosesInternal() const override; + virtual void setSkeletonInternal(AnimSkeleton::ConstPointer skeleton) override; + + void lookUpIndices(); + + AnimPoseVec _poses; + + float _alpha; + bool _enabled; + float _interpDuration; + QString _baseJointName; + QString _tipJointName; + + int _baseParentJointIndex{ -1 }; + int _baseJointIndex{ -1 }; + int _tipJointIndex{ -1 }; + + QString _alphaVar; // float - (0, 1) 0 means underPoses only, 1 means IK only. + QString _enabledVar; // bool + QString _endEffectorRotationVarVar; // string + QString _endEffectorPositionVarVar; // string + + QString _prevEndEffectorRotationVar; + QString _prevEndEffectorPositionVar; + + InterpType _interpType{ InterpType::None }; + float _interpAlphaVel{ 0.0f }; + float _interpAlpha{ 0.0f }; + + AnimChain _snapshotChain; + + bool _lastEnableDebugDrawIKTargets{ false }; + + // no copies + AnimSplineIK(const AnimSplineIK&) = delete; + AnimSplineIK& operator=(const AnimSplineIK&) = delete; + +}; +#endif // hifi_AnimSplineIK_h From 3b5d8db650287d18985a00ad4e9c11bd6880b505 Mon Sep 17 00:00:00 2001 From: amantley Date: Tue, 8 Jan 2019 17:33:14 -0800 Subject: [PATCH 002/112] updated the json to have a spline node at the root --- .../resources/avatar/avatar-animation.json | 3072 ++++++++++------- libraries/animation/src/AnimNodeLoader.cpp | 1 + libraries/animation/src/AnimStateMachine.cpp | 2 +- libraries/animation/src/AnimTwoBoneIK.cpp | 3 + 4 files changed, 1847 insertions(+), 1231 deletions(-) diff --git a/interface/resources/avatar/avatar-animation.json b/interface/resources/avatar/avatar-animation.json index 50fe5019f9..88ee1ff06b 100644 --- a/interface/resources/avatar/avatar-animation.json +++ b/interface/resources/avatar/avatar-animation.json @@ -38,419 +38,274 @@ "children": [ { "id": "userAnimNone", - "type": "poleVectorConstraint", + "type": "splineIK", "data": { + "alpha": 1.0, "enabled": false, - "referenceVector": [0, 0, 1], - "baseJointName": "RightUpLeg", - "midJointName": "RightLeg", - "tipJointName": "RightFoot", - "enabledVar": "rightFootPoleVectorEnabled", - "poleVectorVar": "rightFootPoleVector" + "interpDuration": 15, + "baseJointName": "Hips", + "tipJointName": "Head", + "alphaVar": "splineIKAlpha", + "enabledVar": "splineIKEnabled", + "endEffectorRotationVarVar": "splineIKRotationVar", + "endEffectorPositionVarVar": "splineIKPositionVar" }, "children": [ { - "id": "rightFootIK", - "type": "twoBoneIK", + "id": "rightFootPoleVector", + "type": "poleVectorConstraint", "data": { - "alpha": 1.0, "enabled": false, - "interpDuration": 15, + "referenceVector": [ 0, 0, 1 ], "baseJointName": "RightUpLeg", "midJointName": "RightLeg", "tipJointName": "RightFoot", - "midHingeAxis": [-1, 0, 0], - "alphaVar": "rightFootIKAlpha", - "enabledVar": "rightFootIKEnabled", - "endEffectorRotationVarVar": "rightFootIKRotationVar", - "endEffectorPositionVarVar": "rightFootIKPositionVar" + "enabledVar": "rightFootPoleVectorEnabled", + "poleVectorVar": "rightFootPoleVector" }, "children": [ { - "id": "leftFootPoleVector", - "type": "poleVectorConstraint", + "id": "rightFootIK", + "type": "twoBoneIK", "data": { + "alpha": 1.0, "enabled": false, - "referenceVector": [0, 0, 1], - "baseJointName": "LeftUpLeg", - "midJointName": "LeftLeg", - "tipJointName": "LeftFoot", - "enabledVar": "leftFootPoleVectorEnabled", - "poleVectorVar": "leftFootPoleVector" + "interpDuration": 15, + "baseJointName": "RightUpLeg", + "midJointName": "RightLeg", + "tipJointName": "RightFoot", + "midHingeAxis": [ -1, 0, 0 ], + "alphaVar": "rightFootIKAlpha", + "enabledVar": "rightFootIKEnabled", + "endEffectorRotationVarVar": "rightFootIKRotationVar", + "endEffectorPositionVarVar": "rightFootIKPositionVar" }, "children": [ { - "id": "leftFootIK", - "type": "twoBoneIK", + "id": "leftFootPoleVector", + "type": "poleVectorConstraint", "data": { - "alpha": 1.0, "enabled": false, - "interpDuration": 15, + "referenceVector": [ 0, 0, 1 ], "baseJointName": "LeftUpLeg", "midJointName": "LeftLeg", "tipJointName": "LeftFoot", - "midHingeAxis": [-1, 0, 0], - "alphaVar": "leftFootIKAlpha", - "enabledVar": "leftFootIKEnabled", - "endEffectorRotationVarVar": "leftFootIKRotationVar", - "endEffectorPositionVarVar": "leftFootIKPositionVar" + "enabledVar": "leftFootPoleVectorEnabled", + "poleVectorVar": "leftFootPoleVector" }, "children": [ { - "id": "ikOverlay", - "type": "overlay", + "id": "leftFootIK", + "type": "twoBoneIK", "data": { "alpha": 1.0, - "alphaVar": "ikOverlayAlpha", - "boneSet": "fullBody" + "enabled": false, + "interpDuration": 15, + "baseJointName": "LeftUpLeg", + "midJointName": "LeftLeg", + "tipJointName": "LeftFoot", + "midHingeAxis": [ -1, 0, 0 ], + "alphaVar": "leftFootIKAlpha", + "enabledVar": "leftFootIKEnabled", + "endEffectorRotationVarVar": "leftFootIKRotationVar", + "endEffectorPositionVarVar": "leftFootIKPositionVar" }, "children": [ { - "id": "ik", - "type": "inverseKinematics", - "data": { - "solutionSource": "relaxToUnderPoses", - "solutionSourceVar": "solutionSource", - "targets": [ - { - "jointName": "Hips", - "positionVar": "hipsPosition", - "rotationVar": "hipsRotation", - "typeVar": "hipsType", - "weightVar": "hipsWeight", - "weight": 1.0, - "flexCoefficients": [1] - }, - { - "jointName": "RightHand", - "positionVar": "rightHandPosition", - "rotationVar": "rightHandRotation", - "typeVar": "rightHandType", - "weightVar": "rightHandWeight", - "weight": 1.0, - "flexCoefficients": [1, 0.5, 0.5, 0.2, 0.01, 0.005, 0.001, 0.0, 0.0], - "poleVectorEnabledVar": "rightHandPoleVectorEnabled", - "poleReferenceVectorVar": "rightHandPoleReferenceVector", - "poleVectorVar": "rightHandPoleVector" - }, - { - "jointName": "LeftHand", - "positionVar": "leftHandPosition", - "rotationVar": "leftHandRotation", - "typeVar": "leftHandType", - "weightVar": "leftHandWeight", - "weight": 1.0, - "flexCoefficients": [1, 0.5, 0.5, 0.2, 0.01, 0.005, 0.001, 0.0, 0.0], - "poleVectorEnabledVar": "leftHandPoleVectorEnabled", - "poleReferenceVectorVar": "leftHandPoleReferenceVector", - "poleVectorVar": "leftHandPoleVector" - }, - { - "jointName": "Spine2", - "positionVar": "spine2Position", - "rotationVar": "spine2Rotation", - "typeVar": "spine2Type", - "weightVar": "spine2Weight", - "weight": 2.0, - "flexCoefficients": [1.0, 0.5, 0.25] - }, - { - "jointName": "Head", - "positionVar": "headPosition", - "rotationVar": "headRotation", - "typeVar": "headType", - "weightVar": "headWeight", - "weight": 4.0, - "flexCoefficients": [1, 0.5, 0.25, 0.2, 0.1] - } - ] - }, - "children": [] - }, - { - "id": "defaultPoseOverlay", + "id": "ikOverlay", "type": "overlay", "data": { - "alpha": 0.0, - "alphaVar": "defaultPoseOverlayAlpha", - "boneSet": "fullBody", - "boneSetVar": "defaultPoseOverlayBoneSet" + "alpha": 1.0, + "alphaVar": "ikOverlayAlpha", + "boneSet": "fullBody" }, "children": [ { - "id": "defaultPose", - "type": "defaultPose", + "id": "ik", + "type": "inverseKinematics", "data": { + "solutionSource": "relaxToUnderPoses", + "solutionSourceVar": "solutionSource", + "targets": [ + { + "jointName": "Hips", + "positionVar": "hipsPosition", + "rotationVar": "hipsRotation", + "typeVar": "hipsType", + "weightVar": "hipsWeight", + "weight": 1.0, + "flexCoefficients": [ 1 ] + }, + { + "jointName": "RightHand", + "positionVar": "rightHandPosition", + "rotationVar": "rightHandRotation", + "typeVar": "rightHandType", + "weightVar": "rightHandWeight", + "weight": 1.0, + "flexCoefficients": [ 1, 0.5, 0.5, 0.2, 0.01, 0.005, 0.001, 0.0, 0.0 ], + "poleVectorEnabledVar": "rightHandPoleVectorEnabled", + "poleReferenceVectorVar": "rightHandPoleReferenceVector", + "poleVectorVar": "rightHandPoleVector" + }, + { + "jointName": "LeftHand", + "positionVar": "leftHandPosition", + "rotationVar": "leftHandRotation", + "typeVar": "leftHandType", + "weightVar": "leftHandWeight", + "weight": 1.0, + "flexCoefficients": [ 1, 0.5, 0.5, 0.2, 0.01, 0.005, 0.001, 0.0, 0.0 ], + "poleVectorEnabledVar": "leftHandPoleVectorEnabled", + "poleReferenceVectorVar": "leftHandPoleReferenceVector", + "poleVectorVar": "leftHandPoleVector" + }, + { + "jointName": "Spine2", + "positionVar": "spine2Position", + "rotationVar": "spine2Rotation", + "typeVar": "spine2Type", + "weightVar": "spine2Weight", + "weight": 2.0, + "flexCoefficients": [ 1.0, 0.5, 0.25 ] + }, + { + "jointName": "Head", + "positionVar": "headPosition", + "rotationVar": "headRotation", + "typeVar": "headType", + "weightVar": "headWeight", + "weight": 4.0, + "flexCoefficients": [ 1, 0.5, 0.25, 0.2, 0.1 ] + } + ] }, "children": [] }, { - "id": "rightHandOverlay", + "id": "defaultPoseOverlay", "type": "overlay", "data": { "alpha": 0.0, - "boneSet": "rightHand", - "alphaVar": "rightHandOverlayAlpha" + "alphaVar": "defaultPoseOverlayAlpha", + "boneSet": "fullBody", + "boneSetVar": "defaultPoseOverlayBoneSet" }, "children": [ { - "id": "rightHandStateMachine", - "type": "stateMachine", + "id": "defaultPose", + "type": "defaultPose", "data": { - "currentState": "rightHandGrasp", - "states": [ - { - "id": "rightHandGrasp", - "interpTarget": 3, - "interpDuration": 3, - "transitions": [ - { "var": "isRightIndexPoint", "state": "rightIndexPoint" }, - { "var": "isRightThumbRaise", "state": "rightThumbRaise" }, - { "var": "isRightIndexPointAndThumbRaise", "state": "rightIndexPointAndThumbRaise" } - ] - }, - { - "id": "rightIndexPoint", - "interpTarget": 15, - "interpDuration": 3, - "transitions": [ - { "var": "isRightHandGrasp", "state": "rightHandGrasp" }, - { "var": "isRightThumbRaise", "state": "rightThumbRaise" }, - { "var": "isRightIndexPointAndThumbRaise", "state": "rightIndexPointAndThumbRaise" } - ] - }, - { - "id": "rightThumbRaise", - "interpTarget": 15, - "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" } - ] - } - ] }, - "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": [] - } - ] - } - ] + "children": [] }, { - "id": "leftHandOverlay", + "id": "rightHandOverlay", "type": "overlay", "data": { "alpha": 0.0, - "boneSet": "leftHand", - "alphaVar": "leftHandOverlayAlpha" + "boneSet": "rightHand", + "alphaVar": "rightHandOverlayAlpha" }, "children": [ { - "id": "leftHandStateMachine", + "id": "rightHandStateMachine", "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 +314,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 +328,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 +348,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 +362,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 +382,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 +396,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 +416,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,911 +432,1588 @@ ] }, { - "id": "mainStateMachine", - "type": "stateMachine", + "id": "leftHandOverlay", + "type": "overlay", "data": { - "outputJoints": ["LeftFoot", "RightFoot"], - "currentState": "idle", - "states": [ - { - "id": "idle", - "interpTarget": 20, - "interpDuration": 8, - "interpType": "snapshotPrev", - "transitions": [ - { "var": "isMovingForward", "state": "WALKFWD" }, - { "var": "isMovingBackward", "state": "WALKBWD" }, - { "var": "isMovingRight", "state": "STRAFERIGHT" }, - { "var": "isMovingLeft", "state": "STRAFELEFT" }, - { "var": "isTurningRight", "state": "turnRight" }, - { "var": "isTurningLeft", "state": "turnLeft" }, - { "var": "isFlying", "state": "fly" }, - { "var": "isTakeoffStand", "state": "takeoffStand" }, - { "var": "isTakeoffRun", "state": "TAKEOFFRUN" }, - { "var": "isInAirStand", "state": "inAirStand" }, - { "var": "isInAirRun", "state": "INAIRRUN" }, - { "var": "isMovingRightHmd", "state": "strafeRightHmd" }, - { "var": "isMovingLeftHmd", "state": "strafeLeftHmd" } - ] - }, - { - "id": "idleToWalkFwd", - "interpTarget": 12, - "interpDuration": 8, - "transitions": [ - { "var": "idleToWalkFwdOnDone", "state": "WALKFWD" }, - { "var": "isNotMoving", "state": "idle" }, - { "var": "isMovingBackward", "state": "WALKBWD" }, - { "var": "isMovingRight", "state": "STRAFERIGHT" }, - { "var": "isMovingLeft", "state": "STRAFELEFT" }, - { "var": "isTurningRight", "state": "turnRight" }, - { "var": "isTurningLeft", "state": "turnLeft" }, - { "var": "isFlying", "state": "fly" }, - { "var": "isTakeoffStand", "state": "takeoffStand" }, - { "var": "isTakeoffRun", "state": "TAKEOFFRUN" }, - { "var": "isInAirStand", "state": "inAirStand" }, - { "var": "isInAirRun", "state": "INAIRRUN" }, - { "var": "isMovingRightHmd", "state": "strafeRightHmd" }, - { "var": "isMovingLeftHmd", "state": "strafeLeftHmd" } - ] - }, - { - "id": "idleSettle", - "interpTarget": 15, - "interpDuration": 8, - "interpType": "snapshotPrev", - "transitions": [ - {"var": "idleSettleOnDone", "state": "idle" }, - {"var": "isMovingForward", "state": "WALKFWD" }, - { "var": "isMovingBackward", "state": "WALKBWD" }, - { "var": "isMovingRight", "state": "STRAFERIGHT" }, - { "var": "isMovingLeft", "state": "STRAFELEFT" }, - { "var": "isMovingRightHmd", "state": "strafeRightHmd" }, - { "var": "isMovingLeftHmd", "state": "strafeLeftHmd" }, - { "var": "isTurningRight", "state": "turnRight" }, - { "var": "isTurningLeft", "state": "turnLeft" }, - { "var": "isFlying", "state": "fly" }, - { "var": "isTakeoffStand", "state": "takeoffStand" }, - { "var": "isTakeoffRun", "state": "TAKEOFFRUN" }, - { "var": "isInAirStand", "state": "inAirStand" }, - { "var": "isInAirRun", "state": "INAIRRUN" } - ] - }, - { - "id": "WALKFWD", - "interpTarget": 35, - "interpDuration": 10, - "interpType": "snapshotPrev", - "transitions": [ - { "var": "isNotMoving", "state": "idleSettle" }, - { "var": "isMovingBackward", "state": "WALKBWD" }, - { "var": "isMovingRight", "state": "STRAFERIGHT" }, - { "var": "isMovingLeft", "state": "STRAFELEFT" }, - { "var": "isTurningRight", "state": "turnRight" }, - { "var": "isTurningLeft", "state": "turnLeft" }, - { "var": "isFlying", "state": "fly" }, - { "var": "isTakeoffStand", "state": "takeoffStand" }, - { "var": "isTakeoffRun", "state": "TAKEOFFRUN" }, - { "var": "isInAirStand", "state": "inAirStand" }, - { "var": "isInAirRun", "state": "INAIRRUN" }, - { "var": "isMovingRightHmd", "state": "strafeRightHmd" }, - { "var": "isMovingLeftHmd", "state": "strafeLeftHmd" } - ] - }, - { - "id": "WALKBWD", - "interpTarget": 35, - "interpDuration": 10, - "interpType": "snapshotPrev", - "transitions": [ - { "var": "isNotMoving", "state": "idleSettle" }, - { "var": "isMovingForward", "state": "WALKFWD" }, - { "var": "isMovingRight", "state": "STRAFERIGHT" }, - { "var": "isMovingLeft", "state": "STRAFELEFT" }, - { "var": "isTurningRight", "state": "turnRight" }, - { "var": "isTurningLeft", "state": "turnLeft" }, - { "var": "isFlying", "state": "fly" }, - { "var": "isTakeoffStand", "state": "takeoffStand" }, - { "var": "isTakeoffRun", "state": "TAKEOFFRUN" }, - { "var": "isInAirStand", "state": "inAirStand" }, - { "var": "isInAirRun", "state": "INAIRRUN" }, - { "var": "isMovingRightHmd", "state": "strafeRightHmd" }, - { "var": "isMovingLeftHmd", "state": "strafeLeftHmd" } - ] - }, - { - "id": "STRAFERIGHT", - "interpTarget": 25, - "interpDuration": 8, - "interpType": "snapshotPrev", - "transitions": [ - { "var": "isNotMoving", "state": "idleSettle" }, - { "var": "isMovingForward", "state": "WALKFWD" }, - { "var": "isMovingBackward", "state": "WALKBWD" }, - { "var": "isMovingLeft", "state": "STRAFELEFT" }, - { "var": "isTurningRight", "state": "turnRight" }, - { "var": "isTurningLeft", "state": "turnLeft" }, - { "var": "isFlying", "state": "fly" }, - { "var": "isTakeoffStand", "state": "takeoffStand" }, - { "var": "isTakeoffRun", "state": "TAKEOFFRUN" }, - { "var": "isInAirStand", "state": "inAirStand" }, - { "var": "isInAirRun", "state": "INAIRRUN" }, - { "var": "isMovingRightHmd", "state": "strafeRightHmd" }, - { "var": "isMovingLeftHmd", "state": "strafeLeftHmd" } - ] - }, - { - "id": "STRAFELEFT", - "interpTarget": 25, - "interpDuration": 8, - "interpType": "snapshotPrev", - "transitions": [ - { "var": "isNotMoving", "state": "idleSettle" }, - { "var": "isMovingForward", "state": "WALKFWD" }, - { "var": "isMovingBackward", "state": "WALKBWD" }, - { "var": "isMovingRight", "state": "STRAFERIGHT" }, - { "var": "isTurningRight", "state": "turnRight" }, - { "var": "isTurningLeft", "state": "turnLeft" }, - { "var": "isFlying", "state": "fly" }, - { "var": "isTakeoffStand", "state": "takeoffStand" }, - { "var": "isTakeoffRun", "state": "TAKEOFFRUN" }, - { "var": "isInAirStand", "state": "inAirStand" }, - { "var": "isInAirRun", "state": "INAIRRUN" }, - { "var": "isMovingRightHmd", "state": "strafeRightHmd" }, - { "var": "isMovingLeftHmd", "state": "strafeLeftHmd" } - ] - }, - { - "id": "turnRight", - "interpTarget": 6, - "interpDuration": 8, - "transitions": [ - { "var": "isNotTurning", "state": "idle" }, - { "var": "isMovingForward", "state": "WALKFWD" }, - { "var": "isMovingBackward", "state": "WALKBWD" }, - { "var": "isMovingRight", "state": "STRAFERIGHT" }, - { "var": "isMovingLeft", "state": "STRAFELEFT" }, - { "var": "isTurningLeft", "state": "turnLeft" }, - { "var": "isFlying", "state": "fly" }, - { "var": "isTakeoffStand", "state": "takeoffStand" }, - { "var": "isTakeoffRun", "state": "TAKEOFFRUN" }, - { "var": "isInAirStand", "state": "inAirStand" }, - { "var": "isInAirRun", "state": "INAIRRUN" }, - { "var": "isMovingRightHmd", "state": "strafeRightHmd" }, - { "var": "isMovingLeftHmd", "state": "strafeLeftHmd" } - ] - }, - { - "id": "turnLeft", - "interpTarget": 6, - "interpDuration": 8, - "transitions": [ - { "var": "isNotTurning", "state": "idle" }, - { "var": "isMovingForward", "state": "WALKFWD" }, - { "var": "isMovingBackward", "state": "WALKBWD" }, - { "var": "isMovingRight", "state": "STRAFERIGHT" }, - { "var": "isMovingLeft", "state": "STRAFELEFT" }, - { "var": "isTurningRight", "state": "turnRight" }, - { "var": "isFlying", "state": "fly" }, - { "var": "isTakeoffStand", "state": "takeoffStand" }, - { "var": "isTakeoffRun", "state": "TAKEOFFRUN" }, - { "var": "isInAirStand", "state": "inAirStand" }, - { "var": "isInAirRun", "state": "INAIRRUN" }, - { "var": "isMovingRightHmd", "state": "strafeRightHmd" }, - { "var": "isMovingLeftHmd", "state": "strafeLeftHmd" } - ] - }, - { - "id": "strafeRightHmd", - "interpTarget": 5, - "interpDuration": 8, - "interpType": "snapshotPrev", - "transitions": [ - { "var": "isNotMoving", "state": "idleSettle" }, - { "var": "isMovingForward", "state": "WALKFWD" }, - { "var": "isMovingBackward", "state": "WALKBWD" }, - { "var": "isMovingLeftHmd", "state": "strafeLeftHmd" }, - { "var": "isMovingRight", "state": "STRAFERIGHT" }, - { "var": "isMovingLeft", "state": "STRAFELEFT" }, - { "var": "isTurningRight", "state": "turnRight" }, - { "var": "isTurningLeft", "state": "turnLeft" }, - { "var": "isFlying", "state": "fly" }, - { "var": "isTakeoffStand", "state": "takeoffStand" }, - { "var": "isTakeoffRun", "state": "TAKEOFFRUN" }, - { "var": "isInAirStand", "state": "inAirStand" }, - { "var": "isInAirRun", "state": "INAIRRUN" } - ] - }, - { - "id": "strafeLeftHmd", - "interpTarget": 5, - "interpDuration": 8, - "interpType": "snapshotPrev", - "transitions": [ - { "var": "isNotMoving", "state": "idleSettle" }, - { "var": "isMovingForward", "state": "WALKFWD" }, - { "var": "isMovingBackward", "state": "WALKBWD" }, - { "var": "isMovingRightHmd", "state": "strafeRightHmd" }, - { "var": "isMovingRight", "state": "STRAFERIGHT" }, - { "var": "isMovingLeft", "state": "STRAFELEFT" }, - { "var": "isTurningRight", "state": "turnRight" }, - { "var": "isTurningLeft", "state": "turnLeft" }, - { "var": "isFlying", "state": "fly" }, - { "var": "isTakeoffStand", "state": "takeoffStand" }, - { "var": "isTakeoffRun", "state": "TAKEOFFRUN" }, - { "var": "isInAirStand", "state": "inAirStand" }, - { "var": "isInAirRun", "state": "INAIRRUN" } - ] - }, - { - "id": "fly", - "interpTarget": 6, - "interpDuration": 6, - "transitions": [ - { "var": "isNotFlying", "state": "idleSettle" } - ] - }, - { - "id": "takeoffStand", - "interpTarget": 2, - "interpDuration": 2, - "transitions": [ - { "var": "isNotTakeoff", "state": "inAirStand" } - ] - }, - { - "id": "TAKEOFFRUN", - "interpTarget": 2, - "interpDuration": 2, - "transitions": [ - { "var": "isNotTakeoff", "state": "INAIRRUN" } - ] - }, - { - "id": "inAirStand", - "interpTarget": 3, - "interpDuration": 3, - "interpType": "snapshotPrev", - "transitions": [ - { "var": "isNotInAir", "state": "landStandImpact" } - ] - }, - { - "id": "INAIRRUN", - "interpTarget": 3, - "interpDuration": 3, - "interpType": "snapshotPrev", - "transitions": [ - { "var": "isNotInAir", "state": "WALKFWD" } - ] - }, - { - "id": "landStandImpact", - "interpTarget": 1, - "interpDuration": 1, - "transitions": [ - { "var": "isFlying", "state": "fly" }, - { "var": "isTakeoffStand", "state": "takeoffStand" }, - { "var": "isTakeoffRun", "state": "TAKEOFFRUN" }, - { "var": "landStandImpactOnDone", "state": "landStand" } - ] - }, - { - "id": "landStand", - "interpTarget": 1, - "interpDuration": 1, - "transitions": [ - { "var": "isMovingForward", "state": "WALKFWD" }, - { "var": "isMovingBackward", "state": "WALKBWD" }, - { "var": "isMovingRight", "state": "STRAFERIGHT" }, - { "var": "isMovingLeft", "state": "STRAFELEFT" }, - { "var": "isTurningRight", "state": "turnRight" }, - { "var": "isTurningLeft", "state": "turnLeft" }, - { "var": "isFlying", "state": "fly" }, - { "var": "isTakeoffStand", "state": "takeoffStand" }, - { "var": "isTakeoffRun", "state": "TAKEOFFRUN" }, - { "var": "isInAirStand", "state": "inAirStand" }, - { "var": "isInAirRun", "state": "INAIRRUN" }, - { "var": "landStandOnDone", "state": "idle" }, - { "var": "isMovingRightHmd", "state": "strafeRightHmd" }, - { "var": "isMovingLeftHmd", "state": "strafeLeftHmd" } - ] - }, - { - "id": "LANDRUN", - "interpTarget": 2, - "interpDuration": 2, - "transitions": [ - { "var": "isFlying", "state": "fly" }, - { "var": "isTakeoffStand", "state": "takeoffStand" }, - { "var": "isTakeoffRun", "state": "TAKEOFFRUN" }, - { "var": "landRunOnDone", "state": "WALKFWD" } - ] - } - ] + "alpha": 0.0, + "boneSet": "leftHand", + "alphaVar": "leftHandOverlayAlpha" }, "children": [ { - "id": "idle", + "id": "leftHandStateMachine", "type": "stateMachine", "data": { - "currentState": "idleStand", + "currentState": "leftHandGrasp", "states": [ { - "id": "idleStand", - "interpTarget": 6, - "interpDuration": 10, + "id": "leftHandGrasp", + "interpTarget": 3, + "interpDuration": 3, "transitions": [ - { "var": "isTalking", "state": "idleTalk" } + { + "var": "isLeftIndexPoint", + "state": "leftIndexPoint" + }, + { + "var": "isLeftThumbRaise", + "state": "leftThumbRaise" + }, + { + "var": "isLeftIndexPointAndThumbRaise", + "state": "leftIndexPointAndThumbRaise" + } ] }, { - "id": "idleTalk", - "interpTarget": 6, - "interpDuration": 10, + "id": "leftIndexPoint", + "interpTarget": 15, + "interpDuration": 3, "transitions": [ - { "var": "notIsTalking", "state": "idleStand" } + { + "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": "idleStand", - "type": "clip", + "id": "leftHandGrasp", + "type": "blendLinear", "data": { - "url": "qrc:///avatar/animations/idle.fbx", - "startFrame": 0.0, - "endFrame": 300.0, - "timeScale": 1.0, - "loopFlag": true + "alpha": 0.0, + "alphaVar": "leftHandGraspAlpha" }, - "children": [] + "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": "idleTalk", - "type": "clip", + "id": "leftIndexPoint", + "type": "blendLinear", "data": { - "url": "qrc:///avatar/animations/talk.fbx", - "startFrame": 0.0, - "endFrame": 800.0, - "timeScale": 1.0, - "loopFlag": true + "alpha": 0.0, + "alphaVar": "leftHandGraspAlpha" }, - "children": [] + "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": "WALKFWD", - "type": "blendLinearMove", + "id": "mainStateMachine", + "type": "stateMachine", "data": { - "alpha": 0.0, - "desiredSpeed": 1.4, - "characteristicSpeeds": [0.5, 1.8, 2.3, 3.2, 4.5], - "alphaVar": "moveForwardAlpha", - "desiredSpeedVar": "moveForwardSpeed" + "outputJoints": [ "LeftFoot", "RightFoot" ], + "currentState": "idle", + "states": [ + { + "id": "idle", + "interpTarget": 20, + "interpDuration": 8, + "interpType": "snapshotPrev", + "transitions": [ + { + "var": "isMovingForward", + "state": "WALKFWD" + }, + { + "var": "isMovingBackward", + "state": "WALKBWD" + }, + { + "var": "isMovingRight", + "state": "STRAFERIGHT" + }, + { + "var": "isMovingLeft", + "state": "STRAFELEFT" + }, + { + "var": "isTurningRight", + "state": "turnRight" + }, + { + "var": "isTurningLeft", + "state": "turnLeft" + }, + { + "var": "isFlying", + "state": "fly" + }, + { + "var": "isTakeoffStand", + "state": "takeoffStand" + }, + { + "var": "isTakeoffRun", + "state": "TAKEOFFRUN" + }, + { + "var": "isInAirStand", + "state": "inAirStand" + }, + { + "var": "isInAirRun", + "state": "INAIRRUN" + }, + { + "var": "isMovingRightHmd", + "state": "strafeRightHmd" + }, + { + "var": "isMovingLeftHmd", + "state": "strafeLeftHmd" + } + ] + }, + { + "id": "idleToWalkFwd", + "interpTarget": 12, + "interpDuration": 8, + "transitions": [ + { + "var": "idleToWalkFwdOnDone", + "state": "WALKFWD" + }, + { + "var": "isNotMoving", + "state": "idle" + }, + { + "var": "isMovingBackward", + "state": "WALKBWD" + }, + { + "var": "isMovingRight", + "state": "STRAFERIGHT" + }, + { + "var": "isMovingLeft", + "state": "STRAFELEFT" + }, + { + "var": "isTurningRight", + "state": "turnRight" + }, + { + "var": "isTurningLeft", + "state": "turnLeft" + }, + { + "var": "isFlying", + "state": "fly" + }, + { + "var": "isTakeoffStand", + "state": "takeoffStand" + }, + { + "var": "isTakeoffRun", + "state": "TAKEOFFRUN" + }, + { + "var": "isInAirStand", + "state": "inAirStand" + }, + { + "var": "isInAirRun", + "state": "INAIRRUN" + }, + { + "var": "isMovingRightHmd", + "state": "strafeRightHmd" + }, + { + "var": "isMovingLeftHmd", + "state": "strafeLeftHmd" + } + ] + }, + { + "id": "idleSettle", + "interpTarget": 15, + "interpDuration": 8, + "interpType": "snapshotPrev", + "transitions": [ + { + "var": "idleSettleOnDone", + "state": "idle" + }, + { + "var": "isMovingForward", + "state": "WALKFWD" + }, + { + "var": "isMovingBackward", + "state": "WALKBWD" + }, + { + "var": "isMovingRight", + "state": "STRAFERIGHT" + }, + { + "var": "isMovingLeft", + "state": "STRAFELEFT" + }, + { + "var": "isMovingRightHmd", + "state": "strafeRightHmd" + }, + { + "var": "isMovingLeftHmd", + "state": "strafeLeftHmd" + }, + { + "var": "isTurningRight", + "state": "turnRight" + }, + { + "var": "isTurningLeft", + "state": "turnLeft" + }, + { + "var": "isFlying", + "state": "fly" + }, + { + "var": "isTakeoffStand", + "state": "takeoffStand" + }, + { + "var": "isTakeoffRun", + "state": "TAKEOFFRUN" + }, + { + "var": "isInAirStand", + "state": "inAirStand" + }, + { + "var": "isInAirRun", + "state": "INAIRRUN" + } + ] + }, + { + "id": "WALKFWD", + "interpTarget": 35, + "interpDuration": 10, + "interpType": "snapshotPrev", + "transitions": [ + { + "var": "isNotMoving", + "state": "idleSettle" + }, + { + "var": "isMovingBackward", + "state": "WALKBWD" + }, + { + "var": "isMovingRight", + "state": "STRAFERIGHT" + }, + { + "var": "isMovingLeft", + "state": "STRAFELEFT" + }, + { + "var": "isTurningRight", + "state": "turnRight" + }, + { + "var": "isTurningLeft", + "state": "turnLeft" + }, + { + "var": "isFlying", + "state": "fly" + }, + { + "var": "isTakeoffStand", + "state": "takeoffStand" + }, + { + "var": "isTakeoffRun", + "state": "TAKEOFFRUN" + }, + { + "var": "isInAirStand", + "state": "inAirStand" + }, + { + "var": "isInAirRun", + "state": "INAIRRUN" + }, + { + "var": "isMovingRightHmd", + "state": "strafeRightHmd" + }, + { + "var": "isMovingLeftHmd", + "state": "strafeLeftHmd" + } + ] + }, + { + "id": "WALKBWD", + "interpTarget": 35, + "interpDuration": 10, + "interpType": "snapshotPrev", + "transitions": [ + { + "var": "isNotMoving", + "state": "idleSettle" + }, + { + "var": "isMovingForward", + "state": "WALKFWD" + }, + { + "var": "isMovingRight", + "state": "STRAFERIGHT" + }, + { + "var": "isMovingLeft", + "state": "STRAFELEFT" + }, + { + "var": "isTurningRight", + "state": "turnRight" + }, + { + "var": "isTurningLeft", + "state": "turnLeft" + }, + { + "var": "isFlying", + "state": "fly" + }, + { + "var": "isTakeoffStand", + "state": "takeoffStand" + }, + { + "var": "isTakeoffRun", + "state": "TAKEOFFRUN" + }, + { + "var": "isInAirStand", + "state": "inAirStand" + }, + { + "var": "isInAirRun", + "state": "INAIRRUN" + }, + { + "var": "isMovingRightHmd", + "state": "strafeRightHmd" + }, + { + "var": "isMovingLeftHmd", + "state": "strafeLeftHmd" + } + ] + }, + { + "id": "STRAFERIGHT", + "interpTarget": 25, + "interpDuration": 8, + "interpType": "snapshotPrev", + "transitions": [ + { + "var": "isNotMoving", + "state": "idleSettle" + }, + { + "var": "isMovingForward", + "state": "WALKFWD" + }, + { + "var": "isMovingBackward", + "state": "WALKBWD" + }, + { + "var": "isMovingLeft", + "state": "STRAFELEFT" + }, + { + "var": "isTurningRight", + "state": "turnRight" + }, + { + "var": "isTurningLeft", + "state": "turnLeft" + }, + { + "var": "isFlying", + "state": "fly" + }, + { + "var": "isTakeoffStand", + "state": "takeoffStand" + }, + { + "var": "isTakeoffRun", + "state": "TAKEOFFRUN" + }, + { + "var": "isInAirStand", + "state": "inAirStand" + }, + { + "var": "isInAirRun", + "state": "INAIRRUN" + }, + { + "var": "isMovingRightHmd", + "state": "strafeRightHmd" + }, + { + "var": "isMovingLeftHmd", + "state": "strafeLeftHmd" + } + ] + }, + { + "id": "STRAFELEFT", + "interpTarget": 25, + "interpDuration": 8, + "interpType": "snapshotPrev", + "transitions": [ + { + "var": "isNotMoving", + "state": "idleSettle" + }, + { + "var": "isMovingForward", + "state": "WALKFWD" + }, + { + "var": "isMovingBackward", + "state": "WALKBWD" + }, + { + "var": "isMovingRight", + "state": "STRAFERIGHT" + }, + { + "var": "isTurningRight", + "state": "turnRight" + }, + { + "var": "isTurningLeft", + "state": "turnLeft" + }, + { + "var": "isFlying", + "state": "fly" + }, + { + "var": "isTakeoffStand", + "state": "takeoffStand" + }, + { + "var": "isTakeoffRun", + "state": "TAKEOFFRUN" + }, + { + "var": "isInAirStand", + "state": "inAirStand" + }, + { + "var": "isInAirRun", + "state": "INAIRRUN" + }, + { + "var": "isMovingRightHmd", + "state": "strafeRightHmd" + }, + { + "var": "isMovingLeftHmd", + "state": "strafeLeftHmd" + } + ] + }, + { + "id": "turnRight", + "interpTarget": 6, + "interpDuration": 8, + "transitions": [ + { + "var": "isNotTurning", + "state": "idle" + }, + { + "var": "isMovingForward", + "state": "WALKFWD" + }, + { + "var": "isMovingBackward", + "state": "WALKBWD" + }, + { + "var": "isMovingRight", + "state": "STRAFERIGHT" + }, + { + "var": "isMovingLeft", + "state": "STRAFELEFT" + }, + { + "var": "isTurningLeft", + "state": "turnLeft" + }, + { + "var": "isFlying", + "state": "fly" + }, + { + "var": "isTakeoffStand", + "state": "takeoffStand" + }, + { + "var": "isTakeoffRun", + "state": "TAKEOFFRUN" + }, + { + "var": "isInAirStand", + "state": "inAirStand" + }, + { + "var": "isInAirRun", + "state": "INAIRRUN" + }, + { + "var": "isMovingRightHmd", + "state": "strafeRightHmd" + }, + { + "var": "isMovingLeftHmd", + "state": "strafeLeftHmd" + } + ] + }, + { + "id": "turnLeft", + "interpTarget": 6, + "interpDuration": 8, + "transitions": [ + { + "var": "isNotTurning", + "state": "idle" + }, + { + "var": "isMovingForward", + "state": "WALKFWD" + }, + { + "var": "isMovingBackward", + "state": "WALKBWD" + }, + { + "var": "isMovingRight", + "state": "STRAFERIGHT" + }, + { + "var": "isMovingLeft", + "state": "STRAFELEFT" + }, + { + "var": "isTurningRight", + "state": "turnRight" + }, + { + "var": "isFlying", + "state": "fly" + }, + { + "var": "isTakeoffStand", + "state": "takeoffStand" + }, + { + "var": "isTakeoffRun", + "state": "TAKEOFFRUN" + }, + { + "var": "isInAirStand", + "state": "inAirStand" + }, + { + "var": "isInAirRun", + "state": "INAIRRUN" + }, + { + "var": "isMovingRightHmd", + "state": "strafeRightHmd" + }, + { + "var": "isMovingLeftHmd", + "state": "strafeLeftHmd" + } + ] + }, + { + "id": "strafeRightHmd", + "interpTarget": 5, + "interpDuration": 8, + "interpType": "snapshotPrev", + "transitions": [ + { + "var": "isNotMoving", + "state": "idleSettle" + }, + { + "var": "isMovingForward", + "state": "WALKFWD" + }, + { + "var": "isMovingBackward", + "state": "WALKBWD" + }, + { + "var": "isMovingLeftHmd", + "state": "strafeLeftHmd" + }, + { + "var": "isMovingRight", + "state": "STRAFERIGHT" + }, + { + "var": "isMovingLeft", + "state": "STRAFELEFT" + }, + { + "var": "isTurningRight", + "state": "turnRight" + }, + { + "var": "isTurningLeft", + "state": "turnLeft" + }, + { + "var": "isFlying", + "state": "fly" + }, + { + "var": "isTakeoffStand", + "state": "takeoffStand" + }, + { + "var": "isTakeoffRun", + "state": "TAKEOFFRUN" + }, + { + "var": "isInAirStand", + "state": "inAirStand" + }, + { + "var": "isInAirRun", + "state": "INAIRRUN" + } + ] + }, + { + "id": "strafeLeftHmd", + "interpTarget": 5, + "interpDuration": 8, + "interpType": "snapshotPrev", + "transitions": [ + { + "var": "isNotMoving", + "state": "idleSettle" + }, + { + "var": "isMovingForward", + "state": "WALKFWD" + }, + { + "var": "isMovingBackward", + "state": "WALKBWD" + }, + { + "var": "isMovingRightHmd", + "state": "strafeRightHmd" + }, + { + "var": "isMovingRight", + "state": "STRAFERIGHT" + }, + { + "var": "isMovingLeft", + "state": "STRAFELEFT" + }, + { + "var": "isTurningRight", + "state": "turnRight" + }, + { + "var": "isTurningLeft", + "state": "turnLeft" + }, + { + "var": "isFlying", + "state": "fly" + }, + { + "var": "isTakeoffStand", + "state": "takeoffStand" + }, + { + "var": "isTakeoffRun", + "state": "TAKEOFFRUN" + }, + { + "var": "isInAirStand", + "state": "inAirStand" + }, + { + "var": "isInAirRun", + "state": "INAIRRUN" + } + ] + }, + { + "id": "fly", + "interpTarget": 6, + "interpDuration": 6, + "transitions": [ + { + "var": "isNotFlying", + "state": "idleSettle" + } + ] + }, + { + "id": "takeoffStand", + "interpTarget": 2, + "interpDuration": 2, + "transitions": [ + { + "var": "isNotTakeoff", + "state": "inAirStand" + } + ] + }, + { + "id": "TAKEOFFRUN", + "interpTarget": 2, + "interpDuration": 2, + "transitions": [ + { + "var": "isNotTakeoff", + "state": "INAIRRUN" + } + ] + }, + { + "id": "inAirStand", + "interpTarget": 3, + "interpDuration": 3, + "interpType": "snapshotPrev", + "transitions": [ + { + "var": "isNotInAir", + "state": "landStandImpact" + } + ] + }, + { + "id": "INAIRRUN", + "interpTarget": 3, + "interpDuration": 3, + "interpType": "snapshotPrev", + "transitions": [ + { + "var": "isNotInAir", + "state": "WALKFWD" + } + ] + }, + { + "id": "landStandImpact", + "interpTarget": 1, + "interpDuration": 1, + "transitions": [ + { + "var": "isFlying", + "state": "fly" + }, + { + "var": "isTakeoffStand", + "state": "takeoffStand" + }, + { + "var": "isTakeoffRun", + "state": "TAKEOFFRUN" + }, + { + "var": "landStandImpactOnDone", + "state": "landStand" + } + ] + }, + { + "id": "landStand", + "interpTarget": 1, + "interpDuration": 1, + "transitions": [ + { + "var": "isMovingForward", + "state": "WALKFWD" + }, + { + "var": "isMovingBackward", + "state": "WALKBWD" + }, + { + "var": "isMovingRight", + "state": "STRAFERIGHT" + }, + { + "var": "isMovingLeft", + "state": "STRAFELEFT" + }, + { + "var": "isTurningRight", + "state": "turnRight" + }, + { + "var": "isTurningLeft", + "state": "turnLeft" + }, + { + "var": "isFlying", + "state": "fly" + }, + { + "var": "isTakeoffStand", + "state": "takeoffStand" + }, + { + "var": "isTakeoffRun", + "state": "TAKEOFFRUN" + }, + { + "var": "isInAirStand", + "state": "inAirStand" + }, + { + "var": "isInAirRun", + "state": "INAIRRUN" + }, + { + "var": "landStandOnDone", + "state": "idle" + }, + { + "var": "isMovingRightHmd", + "state": "strafeRightHmd" + }, + { + "var": "isMovingLeftHmd", + "state": "strafeLeftHmd" + } + ] + }, + { + "id": "LANDRUN", + "interpTarget": 2, + "interpDuration": 2, + "transitions": [ + { + "var": "isFlying", + "state": "fly" + }, + { + "var": "isTakeoffStand", + "state": "takeoffStand" + }, + { + "var": "isTakeoffRun", + "state": "TAKEOFFRUN" + }, + { + "var": "landRunOnDone", + "state": "WALKFWD" + } + ] + } + ] }, "children": [ { - "id": "walkFwdShort_c", - "type": "clip", + "id": "idle", + "type": "stateMachine", "data": { - "url": "qrc:///avatar/animations/walk_short_fwd.fbx", - "startFrame": 0.0, - "endFrame": 39.0, - "timeScale": 1.0, - "loopFlag": true + "currentState": "idleStand", + "states": [ + { + "id": "idleStand", + "interpTarget": 6, + "interpDuration": 10, + "transitions": [ + { + "var": "isTalking", + "state": "idleTalk" + } + ] + }, + { + "id": "idleTalk", + "interpTarget": 6, + "interpDuration": 10, + "transitions": [ + { + "var": "notIsTalking", + "state": "idleStand" + } + ] + } + ] }, - "children": [] + "children": [ + { + "id": "idleStand", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/idle.fbx", + "startFrame": 0.0, + "endFrame": 300.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "idleTalk", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/talk.fbx", + "startFrame": 0.0, + "endFrame": 800.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + } + ] }, { - "id": "walkFwdNormal_c", - "type": "clip", + "id": "WALKFWD", + "type": "blendLinearMove", "data": { - "url": "qrc:///avatar/animations/walk_fwd.fbx", - "startFrame": 0.0, - "endFrame": 30.0, - "timeScale": 1.0, - "loopFlag": true + "alpha": 0.0, + "desiredSpeed": 1.4, + "characteristicSpeeds": [ 0.5, 1.8, 2.3, 3.2, 4.5 ], + "alphaVar": "moveForwardAlpha", + "desiredSpeedVar": "moveForwardSpeed" }, - "children": [] + "children": [ + { + "id": "walkFwdShort_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/walk_short_fwd.fbx", + "startFrame": 0.0, + "endFrame": 39.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "walkFwdNormal_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/walk_fwd.fbx", + "startFrame": 0.0, + "endFrame": 30.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "walkFwdFast_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/walk_fwd_fast.fbx", + "startFrame": 0.0, + "endFrame": 25.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "walkFwdJog_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jog_fwd.fbx", + "startFrame": 0.0, + "endFrame": 25.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "walkFwdRun_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/run_fwd.fbx", + "startFrame": 0.0, + "endFrame": 21.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + } + ] }, { - "id": "walkFwdFast_c", + "id": "idleToWalkFwd", "type": "clip", "data": { - "url": "qrc:///avatar/animations/walk_fwd_fast.fbx", - "startFrame": 0.0, - "endFrame": 25.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - }, - { - "id": "walkFwdJog_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/jog_fwd.fbx", - "startFrame": 0.0, - "endFrame": 25.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - }, - { - "id": "walkFwdRun_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/run_fwd.fbx", - "startFrame": 0.0, - "endFrame": 21.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - } - ] - }, - { - "id": "idleToWalkFwd", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/idle_to_walk.fbx", - "startFrame": 1.0, - "endFrame": 13.0, - "timeScale": 1.0, - "loopFlag": false - }, - "children": [] - }, - { - "id": "idleSettle", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/settle_to_idle.fbx", - "startFrame": 1.0, - "endFrame": 59.0, - "timeScale": 1.0, - "loopFlag": false - }, - "children": [] - }, - { - "id": "WALKBWD", - "type": "blendLinearMove", - "data": { - "alpha": 0.0, - "desiredSpeed": 1.4, - "characteristicSpeeds": [0.6, 1.6, 2.3, 3.1], - "alphaVar": "moveBackwardAlpha", - "desiredSpeedVar": "moveBackwardSpeed" - }, - "children": [ - { - "id": "walkBwdShort_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/walk_short_bwd.fbx", - "startFrame": 0.0, - "endFrame": 38.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - }, - { - "id": "walkBwdFast_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/walk_bwd_fast.fbx", - "startFrame": 0.0, - "endFrame": 27.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - }, - { - "id": "jogBwd_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/jog_bwd.fbx", - "startFrame": 0.0, - "endFrame": 24.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - }, - { - "id": "runBwd_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/run_bwd.fbx", - "startFrame": 0.0, - "endFrame": 16.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - } - ] - }, - { - "id": "turnLeft", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/turn_left.fbx", - "startFrame": 0.0, - "endFrame": 32.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - }, - { - "id": "turnRight", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/turn_left.fbx", - "startFrame": 0.0, - "endFrame": 32.0, - "timeScale": 1.0, - "loopFlag": true, - "mirrorFlag": true - }, - "children": [] - }, - { - "id": "STRAFELEFT", - "type": "blendLinearMove", - "data": { - "alpha": 0.0, - "desiredSpeed": 1.4, - "characteristicSpeeds": [0.1, 0.5, 1.0, 2.6, 3.0], - "alphaVar": "moveLateralAlpha", - "desiredSpeedVar": "moveLateralSpeed" - }, - "children": [ - { - "id": "strafeLeftShortStep_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/side_step_short_left.fbx", - "startFrame": 0.0, - "endFrame": 29.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - }, - { - "id": "strafeLeftStep_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/side_step_left.fbx", - "startFrame": 0.0, - "endFrame": 20.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - }, - { - "id": "strafeLeftWalk_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/walk_left.fbx", - "startFrame": 0.0, - "endFrame": 35.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - }, - { - "id": "strafeLeftWalkFast_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/walk_left_fast.fbx", - "startFrame": 0.0, - "endFrame": 21.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - }, - { - "id": "strafeLeftJog_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/jog_left.fbx", - "startFrame": 0.0, - "endFrame": 24.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - } - ] - }, - { - "id": "STRAFERIGHT", - "type": "blendLinearMove", - "data": { - "alpha": 0.0, - "desiredSpeed": 1.4, - "characteristicSpeeds": [0.1, 0.5, 1.0, 2.6, 3.0], - "alphaVar": "moveLateralAlpha", - "desiredSpeedVar": "moveLateralSpeed" - }, - "children": [ { - "id": "strafeRightShortStep_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/side_step_short_left.fbx", - "startFrame": 0.0, - "endFrame": 29.0, - "timeScale": 1.0, - "loopFlag": true, - "mirrorFlag": true - }, - "children": [] - }, - { - "id": "strafeRightStep_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/side_step_left.fbx", - "startFrame": 0.0, - "endFrame": 20.0, - "timeScale": 1.0, - "loopFlag": true, - "mirrorFlag": true - }, - "children": [] - }, - { - "id": "strafeRightWalk_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/walk_left.fbx", - "startFrame": 0.0, - "endFrame": 35.0, - "timeScale": 1.0, - "loopFlag": true, - "mirrorFlag": true - }, - "children": [] - }, - { - "id": "strafeRightFast_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/walk_left_fast.fbx", - "startFrame": 0.0, - "endFrame": 21.0, - "timeScale": 1.0, - "loopFlag": true, - "mirrorFlag": true - }, - "children": [] - }, - { - "id": "strafeRightJog_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/jog_left.fbx", - "startFrame": 0.0, - "endFrame": 24.0, - "timeScale": 1.0, - "loopFlag": true, - "mirrorFlag": true - }, - "children": [] - } - ] - }, - { - "id": "strafeLeftHmd", - "type": "blendLinearMove", - "data": { - "alpha": 0.0, - "desiredSpeed": 1.4, - "characteristicSpeeds": [0, 0.5, 2.5], - "alphaVar": "moveLateralAlpha", - "desiredSpeedVar": "moveLateralSpeed" - }, - "children": [ - { - "id": "stepLeftShort_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/side_step_short_left.fbx", - "startFrame": 0.0, - "endFrame": 29.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - }, - { - "id": "stepLeft_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/side_step_left.fbx", - "startFrame": 0.0, - "endFrame": 20.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - }, - { - "id": "strafeLeftAnim_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/side_step_left_fast.fbx", - "startFrame": 0.0, - "endFrame": 16.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - } - ] - }, - { - "id": "strafeRightHmd", - "type": "blendLinearMove", - "data": { - "alpha": 0.0, - "desiredSpeed": 1.4, - "characteristicSpeeds": [0, 0.5, 2.5], - "alphaVar": "moveLateralAlpha", - "desiredSpeedVar": "moveLateralSpeed" - }, - "children": [ - { - "id": "stepRightShort_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/side_step_short_left.fbx", - "startFrame": 0.0, - "endFrame": 29.0, - "timeScale": 1.0, - "loopFlag": true, - "mirrorFlag": true - }, - "children": [] - }, - { - "id": "stepRight_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/side_step_left.fbx", - "startFrame": 0.0, - "endFrame": 20.0, - "timeScale": 1.0, - "loopFlag": true, - "mirrorFlag": true - }, - "children": [] - }, - { - "id": "strafeRightAnim_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/side_step_left_fast.fbx", - "startFrame": 0.0, - "endFrame": 16.0, - "timeScale": 1.0, - "loopFlag": true, - "mirrorFlag": true - }, - "children": [] - } - ] - }, - { - "id": "fly", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/fly.fbx", - "startFrame": 1.0, - "endFrame": 80.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - }, - { - "id": "takeoffStand", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/jump_standing_launch.fbx", - "startFrame": 2.0, - "endFrame": 16.0, - "timeScale": 1.0, - "loopFlag": false - }, - "children": [] - }, - { - "id": "TAKEOFFRUN", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/jump_running_launch_land.fbx", - "startFrame": 4.0, - "endFrame": 15.0, - "timeScale": 1.0, - "loopFlag": false - }, - "children": [] - }, - { - "id": "inAirStand", - "type": "blendLinear", - "data": { - "alpha": 0.0, - "alphaVar": "inAirAlpha" - }, - "children": [ - { - "id": "inAirStandPreApex", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/jump_standing_apex.fbx", - "startFrame": 0.0, - "endFrame": 0.0, - "timeScale": 1.0, - "loopFlag": false - }, - "children": [] - }, - { - "id": "inAirStandApex", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/jump_standing_apex.fbx", + "url": "qrc:///avatar/animations/idle_to_walk.fbx", "startFrame": 1.0, - "endFrame": 1.0, + "endFrame": 13.0, "timeScale": 1.0, "loopFlag": false }, "children": [] }, { - "id": "inAirStandPostApex", + "id": "idleSettle", "type": "clip", "data": { - "url": "qrc:///avatar/animations/jump_standing_apex.fbx", - "startFrame": 2.0, - "endFrame": 2.0, + "url": "qrc:///avatar/animations/settle_to_idle.fbx", + "startFrame": 1.0, + "endFrame": 59.0, "timeScale": 1.0, "loopFlag": false }, "children": [] - } - ] - }, - { - "id": "INAIRRUN", - "type": "blendLinear", - "data": { - "alpha": 0.0, - "alphaVar": "inAirAlpha" - }, - "children": [ + }, { - "id": "inAirRunPreApex", + "id": "WALKBWD", + "type": "blendLinearMove", + "data": { + "alpha": 0.0, + "desiredSpeed": 1.4, + "characteristicSpeeds": [ 0.6, 1.6, 2.3, 3.1 ], + "alphaVar": "moveBackwardAlpha", + "desiredSpeedVar": "moveBackwardSpeed" + }, + "children": [ + { + "id": "walkBwdShort_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/walk_short_bwd.fbx", + "startFrame": 0.0, + "endFrame": 38.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "walkBwdFast_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/walk_bwd_fast.fbx", + "startFrame": 0.0, + "endFrame": 27.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "jogBwd_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jog_bwd.fbx", + "startFrame": 0.0, + "endFrame": 24.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "runBwd_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/run_bwd.fbx", + "startFrame": 0.0, + "endFrame": 16.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + } + ] + }, + { + "id": "turnLeft", "type": "clip", "data": { - "url": "qrc:///avatar/animations/jump_running_launch_land.fbx", - "startFrame": 16.0, + "url": "qrc:///avatar/animations/turn_left.fbx", + "startFrame": 0.0, + "endFrame": 32.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "turnRight", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/turn_left.fbx", + "startFrame": 0.0, + "endFrame": 32.0, + "timeScale": 1.0, + "loopFlag": true, + "mirrorFlag": true + }, + "children": [] + }, + { + "id": "STRAFELEFT", + "type": "blendLinearMove", + "data": { + "alpha": 0.0, + "desiredSpeed": 1.4, + "characteristicSpeeds": [ 0.1, 0.5, 1.0, 2.6, 3.0 ], + "alphaVar": "moveLateralAlpha", + "desiredSpeedVar": "moveLateralSpeed" + }, + "children": [ + { + "id": "strafeLeftShortStep_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/side_step_short_left.fbx", + "startFrame": 0.0, + "endFrame": 29.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "strafeLeftStep_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/side_step_left.fbx", + "startFrame": 0.0, + "endFrame": 20.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "strafeLeftWalk_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/walk_left.fbx", + "startFrame": 0.0, + "endFrame": 35.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "strafeLeftWalkFast_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/walk_left_fast.fbx", + "startFrame": 0.0, + "endFrame": 21.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "strafeLeftJog_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jog_left.fbx", + "startFrame": 0.0, + "endFrame": 24.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + } + ] + }, + { + "id": "STRAFERIGHT", + "type": "blendLinearMove", + "data": { + "alpha": 0.0, + "desiredSpeed": 1.4, + "characteristicSpeeds": [ 0.1, 0.5, 1.0, 2.6, 3.0 ], + "alphaVar": "moveLateralAlpha", + "desiredSpeedVar": "moveLateralSpeed" + }, + "children": [ + { + "id": "strafeRightShortStep_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/side_step_short_left.fbx", + "startFrame": 0.0, + "endFrame": 29.0, + "timeScale": 1.0, + "loopFlag": true, + "mirrorFlag": true + }, + "children": [] + }, + { + "id": "strafeRightStep_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/side_step_left.fbx", + "startFrame": 0.0, + "endFrame": 20.0, + "timeScale": 1.0, + "loopFlag": true, + "mirrorFlag": true + }, + "children": [] + }, + { + "id": "strafeRightWalk_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/walk_left.fbx", + "startFrame": 0.0, + "endFrame": 35.0, + "timeScale": 1.0, + "loopFlag": true, + "mirrorFlag": true + }, + "children": [] + }, + { + "id": "strafeRightFast_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/walk_left_fast.fbx", + "startFrame": 0.0, + "endFrame": 21.0, + "timeScale": 1.0, + "loopFlag": true, + "mirrorFlag": true + }, + "children": [] + }, + { + "id": "strafeRightJog_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jog_left.fbx", + "startFrame": 0.0, + "endFrame": 24.0, + "timeScale": 1.0, + "loopFlag": true, + "mirrorFlag": true + }, + "children": [] + } + ] + }, + { + "id": "strafeLeftHmd", + "type": "blendLinearMove", + "data": { + "alpha": 0.0, + "desiredSpeed": 1.4, + "characteristicSpeeds": [ 0, 0.5, 2.5 ], + "alphaVar": "moveLateralAlpha", + "desiredSpeedVar": "moveLateralSpeed" + }, + "children": [ + { + "id": "stepLeftShort_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/side_step_short_left.fbx", + "startFrame": 0.0, + "endFrame": 29.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "stepLeft_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/side_step_left.fbx", + "startFrame": 0.0, + "endFrame": 20.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "strafeLeftAnim_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/side_step_left_fast.fbx", + "startFrame": 0.0, + "endFrame": 16.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + } + ] + }, + { + "id": "strafeRightHmd", + "type": "blendLinearMove", + "data": { + "alpha": 0.0, + "desiredSpeed": 1.4, + "characteristicSpeeds": [ 0, 0.5, 2.5 ], + "alphaVar": "moveLateralAlpha", + "desiredSpeedVar": "moveLateralSpeed" + }, + "children": [ + { + "id": "stepRightShort_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/side_step_short_left.fbx", + "startFrame": 0.0, + "endFrame": 29.0, + "timeScale": 1.0, + "loopFlag": true, + "mirrorFlag": true + }, + "children": [] + }, + { + "id": "stepRight_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/side_step_left.fbx", + "startFrame": 0.0, + "endFrame": 20.0, + "timeScale": 1.0, + "loopFlag": true, + "mirrorFlag": true + }, + "children": [] + }, + { + "id": "strafeRightAnim_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/side_step_left_fast.fbx", + "startFrame": 0.0, + "endFrame": 16.0, + "timeScale": 1.0, + "loopFlag": true, + "mirrorFlag": true + }, + "children": [] + } + ] + }, + { + "id": "fly", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/fly.fbx", + "startFrame": 1.0, + "endFrame": 80.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "takeoffStand", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jump_standing_launch.fbx", + "startFrame": 2.0, "endFrame": 16.0, "timeScale": 1.0, "loopFlag": false @@ -1489,66 +2021,146 @@ "children": [] }, { - "id": "inAirRunApex", + "id": "TAKEOFFRUN", "type": "clip", "data": { "url": "qrc:///avatar/animations/jump_running_launch_land.fbx", - "startFrame": 22.0, - "endFrame": 22.0, + "startFrame": 4.0, + "endFrame": 15.0, "timeScale": 1.0, "loopFlag": false }, "children": [] }, { - "id": "inAirRunPostApex", + "id": "inAirStand", + "type": "blendLinear", + "data": { + "alpha": 0.0, + "alphaVar": "inAirAlpha" + }, + "children": [ + { + "id": "inAirStandPreApex", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jump_standing_apex.fbx", + "startFrame": 0.0, + "endFrame": 0.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] + }, + { + "id": "inAirStandApex", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jump_standing_apex.fbx", + "startFrame": 1.0, + "endFrame": 1.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] + }, + { + "id": "inAirStandPostApex", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jump_standing_apex.fbx", + "startFrame": 2.0, + "endFrame": 2.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] + } + ] + }, + { + "id": "INAIRRUN", + "type": "blendLinear", + "data": { + "alpha": 0.0, + "alphaVar": "inAirAlpha" + }, + "children": [ + { + "id": "inAirRunPreApex", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jump_running_launch_land.fbx", + "startFrame": 16.0, + "endFrame": 16.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] + }, + { + "id": "inAirRunApex", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jump_running_launch_land.fbx", + "startFrame": 22.0, + "endFrame": 22.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] + }, + { + "id": "inAirRunPostApex", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jump_running_launch_land.fbx", + "startFrame": 33.0, + "endFrame": 33.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] + } + ] + }, + { + "id": "landStandImpact", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jump_standing_land_settle.fbx", + "startFrame": 1.0, + "endFrame": 6.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] + }, + { + "id": "landStand", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jump_standing_land_settle.fbx", + "startFrame": 6.0, + "endFrame": 68.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] + }, + { + "id": "LANDRUN", "type": "clip", "data": { "url": "qrc:///avatar/animations/jump_running_launch_land.fbx", - "startFrame": 33.0, - "endFrame": 33.0, + "startFrame": 29.0, + "endFrame": 40.0, "timeScale": 1.0, "loopFlag": false }, "children": [] } ] - }, - { - "id": "landStandImpact", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/jump_standing_land_settle.fbx", - "startFrame": 1.0, - "endFrame": 6.0, - "timeScale": 1.0, - "loopFlag": false - }, - "children": [] - }, - { - "id": "landStand", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/jump_standing_land_settle.fbx", - "startFrame": 6.0, - "endFrame": 68.0, - "timeScale": 1.0, - "loopFlag": false - }, - "children": [] - }, - { - "id": "LANDRUN", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/jump_running_launch_land.fbx", - "startFrame": 29.0, - "endFrame": 40.0, - "timeScale": 1.0, - "loopFlag": false - }, - "children": [] } ] } diff --git a/libraries/animation/src/AnimNodeLoader.cpp b/libraries/animation/src/AnimNodeLoader.cpp index 562a614b4a..ec9099df8b 100644 --- a/libraries/animation/src/AnimNodeLoader.cpp +++ b/libraries/animation/src/AnimNodeLoader.cpp @@ -63,6 +63,7 @@ static const char* animNodeTypeToString(AnimNode::Type type) { case AnimNode::Type::InverseKinematics: return "inverseKinematics"; case AnimNode::Type::DefaultPose: return "defaultPose"; case AnimNode::Type::TwoBoneIK: return "twoBoneIK"; + case AnimNode::Type::SplineIK: return "splineIK"; case AnimNode::Type::PoleVectorConstraint: return "poleVectorConstraint"; case AnimNode::Type::NumTypes: return nullptr; }; diff --git a/libraries/animation/src/AnimStateMachine.cpp b/libraries/animation/src/AnimStateMachine.cpp index fb13b8e71c..3042ad20f0 100644 --- a/libraries/animation/src/AnimStateMachine.cpp +++ b/libraries/animation/src/AnimStateMachine.cpp @@ -22,7 +22,7 @@ AnimStateMachine::~AnimStateMachine() { } const AnimPoseVec& AnimStateMachine::evaluate(const AnimVariantMap& animVars, const AnimContext& context, float dt, AnimVariantMap& triggersOut) { - + qCDebug(animation) << "evaluating state machine"; float parentDebugAlpha = context.getDebugAlpha(_id); QString desiredStateID = animVars.lookup(_currentStateVar, _currentState->getID()); diff --git a/libraries/animation/src/AnimTwoBoneIK.cpp b/libraries/animation/src/AnimTwoBoneIK.cpp index 8960b15940..d970e6b862 100644 --- a/libraries/animation/src/AnimTwoBoneIK.cpp +++ b/libraries/animation/src/AnimTwoBoneIK.cpp @@ -46,10 +46,13 @@ AnimTwoBoneIK::~AnimTwoBoneIK() { const AnimPoseVec& AnimTwoBoneIK::evaluate(const AnimVariantMap& animVars, const AnimContext& context, float dt, AnimVariantMap& triggersOut) { + qCDebug(animation) << "evaluating the 2 bone IK"; + assert(_children.size() == 1); if (_children.size() != 1) { return _poses; } + // evalute underPoses AnimPoseVec underPoses = _children[0]->evaluate(animVars, context, dt, triggersOut); From bd9405aef82575972fa3340c2907c50ac45f9601 Mon Sep 17 00:00:00 2001 From: amantley Date: Thu, 10 Jan 2019 10:27:15 -0800 Subject: [PATCH 003/112] add arm ik class for cleanup of inverse kinematics --- libraries/animation/src/AnimArmIK.cpp | 40 +++++++++++++++++++ libraries/animation/src/AnimArmIK.h | 34 ++++++++++++++++ .../animation/src/AnimInverseKinematics.cpp | 4 +- 3 files changed, 77 insertions(+), 1 deletion(-) create mode 100644 libraries/animation/src/AnimArmIK.cpp create mode 100644 libraries/animation/src/AnimArmIK.h diff --git a/libraries/animation/src/AnimArmIK.cpp b/libraries/animation/src/AnimArmIK.cpp new file mode 100644 index 0000000000..202e8c8420 --- /dev/null +++ b/libraries/animation/src/AnimArmIK.cpp @@ -0,0 +1,40 @@ +// +// AnimArmIK.cpp +// +// Created by Angus Antley on 1/9/19. +// Copyright (c) 2019 High Fidelity, Inc. All rights reserved. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "AnimArmIK.h" + +#include + +#include "AnimationLogging.h" +#include "AnimUtil.h" + +AnimArmIK::AnimArmIK(const QString& id, float alpha, bool enabled, float interpDuration, + const QString& baseJointName, const QString& midJointName, + const QString& tipJointName, const glm::vec3& midHingeAxis, + const QString& alphaVar, const QString& enabledVar, + const QString& endEffectorRotationVarVar, const QString& endEffectorPositionVarVar) : + AnimTwoBoneIK(id, alpha, enabled, interpDuration, baseJointName, midJointName, tipJointName, midHingeAxis, alphaVar, enabledVar, endEffectorRotationVarVar, endEffectorPositionVarVar) { + +} + +AnimArmIK::~AnimArmIK() { + +} + +const AnimPoseVec& AnimArmIK::evaluate(const AnimVariantMap& animVars, const AnimContext& context, float dt, AnimVariantMap& triggersOut) { + qCDebug(animation) << "evaluating the arm IK"; + + assert(_children.size() == 1); + if (_children.size() != 1) { + return _poses; + } else { + return _poses; + } +} \ No newline at end of file diff --git a/libraries/animation/src/AnimArmIK.h b/libraries/animation/src/AnimArmIK.h new file mode 100644 index 0000000000..26f79a1b9c --- /dev/null +++ b/libraries/animation/src/AnimArmIK.h @@ -0,0 +1,34 @@ +// +// AnimArmIK.h +// +// Created by Angus Antley on 1/9/19. +// Copyright (c) 2019 High Fidelity, Inc. All rights reserved. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_AnimArmIK_h +#define hifi_AnimArmIK_h + +//#include "AnimNode.h" +#include "AnimTwoBoneIK.h" +//#include "AnimChain.h" + +// Simple two bone IK chain +class AnimArmIK : public AnimTwoBoneIK { +public: + AnimArmIK(const QString& id, float alpha, bool enabled, float interpDuration, + const QString& baseJointName, const QString& midJointName, + const QString& tipJointName, const glm::vec3& midHingeAxis, + const QString& alphaVar, const QString& enabledVar, + const QString& endEffectorRotationVarVar, const QString& endEffectorPositionVarVar); + virtual ~AnimArmIK(); + virtual const AnimPoseVec& evaluate(const AnimVariantMap& animVars, const AnimContext& context, float dt, AnimVariantMap& triggersOut) override; + +protected: + +}; + +#endif // hifi_AnimArmIK_h + diff --git a/libraries/animation/src/AnimInverseKinematics.cpp b/libraries/animation/src/AnimInverseKinematics.cpp index a1809f3438..a6dcf5b2d9 100644 --- a/libraries/animation/src/AnimInverseKinematics.cpp +++ b/libraries/animation/src/AnimInverseKinematics.cpp @@ -237,6 +237,7 @@ void AnimInverseKinematics::solve(const AnimContext& context, const std::vector< // solve all targets for (size_t i = 0; i < targets.size(); i++) { + qCDebug(animation) << "target id: " << targets[i].getIndex() << " and type " << (int)targets[i].getType(); switch (targets[i].getType()) { case IKTarget::Type::Unknown: break; @@ -859,6 +860,7 @@ void AnimInverseKinematics::solveTargetWithSpline(const AnimContext& context, co //virtual const AnimPoseVec& AnimInverseKinematics::evaluate(const AnimVariantMap& animVars, const AnimContext& context, float dt, AnimVariantMap& triggersOut) { // don't call this function, call overlay() instead + qCDebug(animation) << "called evaluate for inverse kinematics"; assert(false); return _relativePoses; } @@ -869,7 +871,7 @@ const AnimPoseVec& AnimInverseKinematics::overlay(const AnimVariantMap& animVars // disable IK on android return underPoses; #endif - + qCDebug(animation) << "called overlay for inverse kinematics"; // allows solutionSource to be overridden by an animVar auto solutionSource = animVars.lookup(_solutionSourceVar, (int)_solutionSource); From 33ff5188c11b949fff7371c9ec155edffae0d52e Mon Sep 17 00:00:00 2001 From: amantley Date: Tue, 15 Jan 2019 18:28:29 -0800 Subject: [PATCH 004/112] adding the spline code to the splineik class --- libraries/animation/src/AnimSplineIK.cpp | 230 ++++++++++++++++++++++- libraries/animation/src/AnimSplineIK.h | 17 ++ 2 files changed, 246 insertions(+), 1 deletion(-) diff --git a/libraries/animation/src/AnimSplineIK.cpp b/libraries/animation/src/AnimSplineIK.cpp index db6b6864b1..65d7bfc821 100644 --- a/libraries/animation/src/AnimSplineIK.cpp +++ b/libraries/animation/src/AnimSplineIK.cpp @@ -44,10 +44,46 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const if (_children.size() != 1) { return _poses; } - // evalute underPoses AnimPoseVec underPoses = _children[0]->evaluate(animVars, context, dt, triggersOut); _poses = underPoses; + + // check to see if we actually need absolute poses. + AnimPoseVec absolutePoses; + absolutePoses.resize(_poses.size()); + computeAbsolutePoses(absolutePoses); + + IKTarget target; + int jointIndex = _skeleton->nameToJointIndex("Head"); + if (jointIndex != -1) { + target.setType(animVars.lookup("HeadType", (int)IKTarget::Type::RotationAndPosition)); + target.setIndex(jointIndex); + AnimPose absPose = _skeleton->getAbsolutePose(jointIndex, _poses); + glm::quat rotation = animVars.lookupRigToGeometry("headRotation", absPose.rot()); + glm::vec3 translation = animVars.lookupRigToGeometry("headPosition", absPose.trans()); + float weight = animVars.lookup("headWeight", "4.0"); + + target.setPose(rotation, translation); + target.setWeight(weight); + const float* flexCoefficients = new float[5]{ 1.0f, 0.5f, 0.25f, 0.2f, 0.1f }; + target.setFlexCoefficients(4, flexCoefficients); + + // record the index of the hips ik target. + if (target.getIndex() == _hipsIndex) { + _hipsTargetIndex = 1; + } + } + if (_poses.size() > 0) { + AnimChain jointChain; + jointChain.buildFromRelativePoses(_skeleton, _poses, target.getIndex()); + + // for each target solve target with spline + + solveTargetWithSpline(context, target, absolutePoses, false, jointChain); + qCDebug(animation) << "made it past the spline solve code"; + } + // we need to blend the old joint chain with the current joint chain, otherwise known as: _snapShotChain + /**/ return _poses; } @@ -66,6 +102,20 @@ void AnimSplineIK::lookUpIndices() { } } +void AnimSplineIK::computeAbsolutePoses(AnimPoseVec& absolutePoses) const { + int numJoints = (int)_poses.size(); + assert(numJoints <= _skeleton->getNumJoints()); + assert(numJoints == (int)absolutePoses.size()); + for (int i = 0; i < numJoints; ++i) { + int parentIndex = _skeleton->getParentIndex(i); + if (parentIndex < 0) { + absolutePoses[i] = _poses[i]; + } else { + absolutePoses[i] = absolutePoses[parentIndex] * _poses[i]; + } + } +} + // for AnimDebugDraw rendering const AnimPoseVec& AnimSplineIK::getPosesInternal() const { return _poses; @@ -73,5 +123,183 @@ const AnimPoseVec& AnimSplineIK::getPosesInternal() const { void AnimSplineIK::setSkeletonInternal(AnimSkeleton::ConstPointer skeleton) { AnimNode::setSkeletonInternal(skeleton); + _headIndex = _skeleton->nameToJointIndex("Head"); + _hipsIndex = _skeleton->nameToJointIndex("Hips"); lookUpIndices(); +} + +static CubicHermiteSplineFunctorWithArcLength computeSplineFromTipAndBase(const AnimPose& tipPose, const AnimPose& basePose, float baseGain = 1.0f, float tipGain = 1.0f) { + float linearDistance = glm::length(basePose.trans() - tipPose.trans()); + glm::vec3 p0 = basePose.trans(); + glm::vec3 m0 = baseGain * linearDistance * (basePose.rot() * Vectors::UNIT_Y); + glm::vec3 p1 = tipPose.trans(); + glm::vec3 m1 = tipGain * linearDistance * (tipPose.rot() * Vectors::UNIT_Y); + + return CubicHermiteSplineFunctorWithArcLength(p0, m0, p1, m1); +} + +void AnimSplineIK::solveTargetWithSpline(const AnimContext& context, const IKTarget& target, const AnimPoseVec& absolutePoses, bool debug, AnimChain& chainInfoOut) const { + + const int baseIndex = _hipsIndex; + + // build spline from tip to base + AnimPose tipPose = AnimPose(glm::vec3(1.0f), target.getRotation(), target.getTranslation()); + AnimPose basePose = absolutePoses[baseIndex]; + CubicHermiteSplineFunctorWithArcLength spline; + if (target.getIndex() == _headIndex) { + // set gain factors so that more curvature occurs near the tip of the spline. + const float HIPS_GAIN = 0.5f; + const float HEAD_GAIN = 1.0f; + spline = computeSplineFromTipAndBase(tipPose, basePose, HIPS_GAIN, HEAD_GAIN); + } else { + spline = computeSplineFromTipAndBase(tipPose, basePose); + } + float totalArcLength = spline.arcLength(1.0f); + + // This prevents the rotation interpolation from rotating the wrong physical way (but correct mathematical way) + // when the head is arched backwards very far. + glm::quat halfRot = safeLerp(basePose.rot(), tipPose.rot(), 0.5f); + if (glm::dot(halfRot * Vectors::UNIT_Z, basePose.rot() * Vectors::UNIT_Z) < 0.0f) { + tipPose.rot() = -tipPose.rot(); + } + qCDebug(animation) << "spot 1"; + // find or create splineJointInfo for this target + const std::vector* splineJointInfoVec = findOrCreateSplineJointInfo(context, target); + + if (splineJointInfoVec && splineJointInfoVec->size() > 0) { + const int baseParentIndex = _skeleton->getParentIndex(baseIndex); + AnimPose parentAbsPose = (baseParentIndex >= 0) ? absolutePoses[baseParentIndex] : AnimPose(); + qCDebug(animation) << "spot 2"; + // go thru splineJointInfoVec backwards (base to tip) + for (int i = (int)splineJointInfoVec->size() - 1; i >= 0; i--) { + const SplineJointInfo& splineJointInfo = (*splineJointInfoVec)[i]; + float t = spline.arcLengthInverse(splineJointInfo.ratio * totalArcLength); + glm::vec3 trans = spline(t); + + // for head splines, preform most twist toward the tip by using ease in function. t^2 + float rotT = t; + if (target.getIndex() == _headIndex) { + rotT = t * t; + } + glm::quat twistRot = safeLerp(basePose.rot(), tipPose.rot(), rotT); + + // compute the rotation by using the derivative of the spline as the y-axis, and the twistRot x-axis + glm::vec3 y = glm::normalize(spline.d(t)); + glm::vec3 x = twistRot * Vectors::UNIT_X; + glm::vec3 u, v, w; + generateBasisVectors(y, x, v, u, w); + glm::mat3 m(u, v, glm::cross(u, v)); + glm::quat rot = glm::normalize(glm::quat_cast(m)); + + AnimPose desiredAbsPose = AnimPose(glm::vec3(1.0f), rot, trans) * splineJointInfo.offsetPose; + + // apply flex coefficent + AnimPose flexedAbsPose; + ::blend(1, &absolutePoses[splineJointInfo.jointIndex], &desiredAbsPose, target.getFlexCoefficient(i), &flexedAbsPose); + + AnimPose relPose = parentAbsPose.inverse() * flexedAbsPose; + + bool constrained = false; + if (splineJointInfo.jointIndex != _hipsIndex) { + // constrain the amount the spine can stretch or compress + float length = glm::length(relPose.trans()); + const float EPSILON = 0.0001f; + if (length > EPSILON) { + float defaultLength = glm::length(_skeleton->getRelativeDefaultPose(splineJointInfo.jointIndex).trans()); + const float STRETCH_COMPRESS_PERCENTAGE = 0.15f; + const float MAX_LENGTH = defaultLength * (1.0f + STRETCH_COMPRESS_PERCENTAGE); + const float MIN_LENGTH = defaultLength * (1.0f - STRETCH_COMPRESS_PERCENTAGE); + if (length > MAX_LENGTH) { + relPose.trans() = (relPose.trans() / length) * MAX_LENGTH; + constrained = true; + } else if (length < MIN_LENGTH) { + relPose.trans() = (relPose.trans() / length) * MIN_LENGTH; + constrained = true; + } + } else { + relPose.trans() = glm::vec3(0.0f); + } + } + // note we are ignoring the constrained info for now. + if (!chainInfoOut.setRelativePoseAtJointIndex(splineJointInfo.jointIndex, relPose)) { + qCDebug(animation) << "we didn't find the joint index for the spline!!!!"; + } + + parentAbsPose = flexedAbsPose; + } + } + + if (debug) { + //debugDrawIKChain(jointChainInfoOut, context); + } +} + +const std::vector* AnimSplineIK::findOrCreateSplineJointInfo(const AnimContext& context, const IKTarget& target) const { + // find or create splineJointInfo for this target + auto iter = _splineJointInfoMap.find(target.getIndex()); + if (iter != _splineJointInfoMap.end()) { + return &(iter->second); + } else { + computeAndCacheSplineJointInfosForIKTarget(context, target); + auto iter = _splineJointInfoMap.find(target.getIndex()); + if (iter != _splineJointInfoMap.end()) { + return &(iter->second); + } + } + + return nullptr; +} + +// pre-compute information about each joint influenced by this spline IK target. +void AnimSplineIK::computeAndCacheSplineJointInfosForIKTarget(const AnimContext& context, const IKTarget& target) const { + std::vector splineJointInfoVec; + + // build spline between the default poses. + AnimPose tipPose = _skeleton->getAbsoluteDefaultPose(target.getIndex()); + AnimPose basePose = _skeleton->getAbsoluteDefaultPose(_hipsIndex); + + CubicHermiteSplineFunctorWithArcLength spline; + if (target.getIndex() == _headIndex) { + // set gain factors so that more curvature occurs near the tip of the spline. + const float HIPS_GAIN = 0.5f; + const float HEAD_GAIN = 1.0f; + spline = computeSplineFromTipAndBase(tipPose, basePose, HIPS_GAIN, HEAD_GAIN); + } else { + spline = computeSplineFromTipAndBase(tipPose, basePose); + } + + // measure the total arc length along the spline + float totalArcLength = spline.arcLength(1.0f); + + glm::vec3 baseToTip = tipPose.trans() - basePose.trans(); + float baseToTipLength = glm::length(baseToTip); + glm::vec3 baseToTipNormal = baseToTip / baseToTipLength; + + int index = target.getIndex(); + int endIndex = _skeleton->getParentIndex(_hipsIndex); + while (index != endIndex) { + AnimPose defaultPose = _skeleton->getAbsoluteDefaultPose(index); + + float ratio = glm::dot(defaultPose.trans() - basePose.trans(), baseToTipNormal) / baseToTipLength; + + // compute offset from spline to the default pose. + float t = spline.arcLengthInverse(ratio * totalArcLength); + + // compute the rotation by using the derivative of the spline as the y-axis, and the defaultPose x-axis + glm::vec3 y = glm::normalize(spline.d(t)); + glm::vec3 x = defaultPose.rot() * Vectors::UNIT_X; + glm::vec3 u, v, w; + generateBasisVectors(y, x, v, u, w); + glm::mat3 m(u, v, glm::cross(u, v)); + glm::quat rot = glm::normalize(glm::quat_cast(m)); + + AnimPose pose(glm::vec3(1.0f), rot, spline(t)); + AnimPose offsetPose = pose.inverse() * defaultPose; + + SplineJointInfo splineJointInfo = { index, ratio, offsetPose }; + splineJointInfoVec.push_back(splineJointInfo); + index = _skeleton->getParentIndex(index); + } + + _splineJointInfoMap[target.getIndex()] = splineJointInfoVec; } \ No newline at end of file diff --git a/libraries/animation/src/AnimSplineIK.h b/libraries/animation/src/AnimSplineIK.h index 36a29971a0..79f012365a 100644 --- a/libraries/animation/src/AnimSplineIK.h +++ b/libraries/animation/src/AnimSplineIK.h @@ -12,6 +12,7 @@ #define hifi_AnimSplineIK_h #include "AnimNode.h" +#include "IKTarget.h" #include "AnimChain.h" // Spline IK for the spine @@ -34,6 +35,8 @@ protected: NumTypes }; + void computeAbsolutePoses(AnimPoseVec& absolutePoses) const; + // for AnimDebugDraw rendering virtual const AnimPoseVec& getPosesInternal() const override; virtual void setSkeletonInternal(AnimSkeleton::ConstPointer skeleton) override; @@ -51,6 +54,9 @@ protected: int _baseParentJointIndex{ -1 }; int _baseJointIndex{ -1 }; int _tipJointIndex{ -1 }; + int _headIndex{ -1 }; + int _hipsIndex{ -1 }; + int _hipsTargetIndex{ -1 }; QString _alphaVar; // float - (0, 1) 0 means underPoses only, 1 means IK only. QString _enabledVar; // bool @@ -66,7 +72,18 @@ protected: AnimChain _snapshotChain; + // used to pre-compute information about each joint influeced by a spline IK target. + struct SplineJointInfo { + int jointIndex; // joint in the skeleton that this information pertains to. + float ratio; // percentage (0..1) along the spline for this joint. + AnimPose offsetPose; // local offset from the spline to the joint. + }; + bool _lastEnableDebugDrawIKTargets{ false }; + void AnimSplineIK::solveTargetWithSpline(const AnimContext& context, const IKTarget& target, const AnimPoseVec& absolutePoses, bool debug, AnimChain& chainInfoOut) const; + void computeAndCacheSplineJointInfosForIKTarget(const AnimContext& context, const IKTarget& target) const; + const std::vector* findOrCreateSplineJointInfo(const AnimContext& context, const IKTarget& target) const; + mutable std::map> _splineJointInfoMap; // no copies AnimSplineIK(const AnimSplineIK&) = delete; From e5b16ef17466d2dae88a31704f5994bf3dc45192 Mon Sep 17 00:00:00 2001 From: amantley Date: Wed, 16 Jan 2019 18:31:52 -0800 Subject: [PATCH 005/112] implemented the splineIK in animSplineIK.cpp, todo: disable animinversekinematic.cpp --- .../resources/avatar/avatar-animation.json | 2 +- .../animation/src/AnimInverseKinematics.cpp | 13 ++++++-- libraries/animation/src/AnimSplineIK.cpp | 32 +++++++++++++------ libraries/animation/src/AnimStateMachine.cpp | 1 - libraries/animation/src/AnimTwoBoneIK.cpp | 2 -- libraries/fbx/src/FBXSerializer.cpp | 1 + 6 files changed, 35 insertions(+), 16 deletions(-) diff --git a/interface/resources/avatar/avatar-animation.json b/interface/resources/avatar/avatar-animation.json index 88ee1ff06b..16523afba3 100644 --- a/interface/resources/avatar/avatar-animation.json +++ b/interface/resources/avatar/avatar-animation.json @@ -173,7 +173,7 @@ "jointName": "Head", "positionVar": "headPosition", "rotationVar": "headRotation", - "typeVar": "headType", + "typeVar": "spine2Type", "weightVar": "headWeight", "weight": 4.0, "flexCoefficients": [ 1, 0.5, 0.25, 0.2, 0.1 ] diff --git a/libraries/animation/src/AnimInverseKinematics.cpp b/libraries/animation/src/AnimInverseKinematics.cpp index a6dcf5b2d9..e5509dc43d 100644 --- a/libraries/animation/src/AnimInverseKinematics.cpp +++ b/libraries/animation/src/AnimInverseKinematics.cpp @@ -237,12 +237,19 @@ void AnimInverseKinematics::solve(const AnimContext& context, const std::vector< // solve all targets for (size_t i = 0; i < targets.size(); i++) { - qCDebug(animation) << "target id: " << targets[i].getIndex() << " and type " << (int)targets[i].getType(); + // qCDebug(animation) << "target id: " << targets[i].getIndex() << " and type " << (int)targets[i].getType(); switch (targets[i].getType()) { case IKTarget::Type::Unknown: break; case IKTarget::Type::Spline: solveTargetWithSpline(context, targets[i], absolutePoses, debug, jointChainInfoVec[i]); + //if (jointChainInfoVec[i].target.getIndex() == _skeleton->nameToJointIndex("Head")) { + // qCDebug(animation) << "AnimIK spline index is " << targets[i].getIndex() << " and chain info size is " << jointChainInfoVec[i].jointInfoVec.size(); + for (int w = 0; w < jointChainInfoVec[i].jointInfoVec.size(); w++) { + // qCDebug(animation) << "joint " << jointChainInfoVec[i].jointInfoVec[w].jointIndex << " rotation is " << jointChainInfoVec[i].jointInfoVec[w].rot; + // qCDebug(animation) << "joint " << jointChainInfoVec[i].jointInfoVec[w].jointIndex << " translation is " << jointChainInfoVec[i].jointInfoVec[w].trans; + } + //} break; default: solveTargetWithCCD(context, targets[i], absolutePoses, debug, jointChainInfoVec[i]); @@ -259,6 +266,7 @@ void AnimInverseKinematics::solve(const AnimContext& context, const std::vector< // ease in expo alpha = 1.0f - powf(2.0f, -10.0f * alpha); + qCDebug(animation) << "the alpha for joint chains is " << alpha; size_t chainSize = std::min(_prevJointChainInfoVec[i].jointInfoVec.size(), jointChainInfoVec[i].jointInfoVec.size()); @@ -361,6 +369,7 @@ void AnimInverseKinematics::solve(const AnimContext& context, const std::vector< // copy jointChainInfoVec into _prevJointChainInfoVec, and update timers for (size_t i = 0; i < jointChainInfoVec.size(); i++) { _prevJointChainInfoVec[i].timer = _prevJointChainInfoVec[i].timer - dt; + //qCDebug(animation) << "the alpha for joint chains is " << _prevJointChainInfoVec[i].timer; if (_prevJointChainInfoVec[i].timer <= 0.0f) { _prevJointChainInfoVec[i] = jointChainInfoVec[i]; _prevJointChainInfoVec[i].target = targets[i]; @@ -860,7 +869,6 @@ void AnimInverseKinematics::solveTargetWithSpline(const AnimContext& context, co //virtual const AnimPoseVec& AnimInverseKinematics::evaluate(const AnimVariantMap& animVars, const AnimContext& context, float dt, AnimVariantMap& triggersOut) { // don't call this function, call overlay() instead - qCDebug(animation) << "called evaluate for inverse kinematics"; assert(false); return _relativePoses; } @@ -871,7 +879,6 @@ const AnimPoseVec& AnimInverseKinematics::overlay(const AnimVariantMap& animVars // disable IK on android return underPoses; #endif - qCDebug(animation) << "called overlay for inverse kinematics"; // allows solutionSource to be overridden by an animVar auto solutionSource = animVars.lookup(_solutionSourceVar, (int)_solutionSource); diff --git a/libraries/animation/src/AnimSplineIK.cpp b/libraries/animation/src/AnimSplineIK.cpp index 65d7bfc821..442112e8f0 100644 --- a/libraries/animation/src/AnimSplineIK.cpp +++ b/libraries/animation/src/AnimSplineIK.cpp @@ -14,6 +14,8 @@ #include #include "AnimUtil.h" +static const float JOINT_CHAIN_INTERP_TIME = 0.5f; + AnimSplineIK::AnimSplineIK(const QString& id, float alpha, bool enabled, float interpDuration, const QString& baseJointName, const QString& tipJointName, @@ -39,7 +41,6 @@ AnimSplineIK::~AnimSplineIK() { } const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const AnimContext& context, float dt, AnimVariantMap& triggersOut) { - qCDebug(animation) << "evaluating the spline function"; assert(_children.size() == 1); if (_children.size() != 1) { return _poses; @@ -56,7 +57,7 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const IKTarget target; int jointIndex = _skeleton->nameToJointIndex("Head"); if (jointIndex != -1) { - target.setType(animVars.lookup("HeadType", (int)IKTarget::Type::RotationAndPosition)); + target.setType(animVars.lookup("headType", (int)IKTarget::Type::RotationAndPosition)); target.setIndex(jointIndex); AnimPose absPose = _skeleton->getAbsolutePose(jointIndex, _poses); glm::quat rotation = animVars.lookupRigToGeometry("headRotation", absPose.rot()); @@ -74,15 +75,30 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const } } if (_poses.size() > 0) { - AnimChain jointChain; - jointChain.buildFromRelativePoses(_skeleton, _poses, target.getIndex()); + AnimChain jointChain; + _snapshotChain.buildFromRelativePoses(_skeleton, _poses, target.getIndex()); + jointChain.buildFromRelativePoses(_skeleton, _poses, target.getIndex()); - // for each target solve target with spline - + // for each target solve target with spline solveTargetWithSpline(context, target, absolutePoses, false, jointChain); - qCDebug(animation) << "made it past the spline solve code"; + + // qCDebug(animation) << "AnimSpline Joint chain length " << jointChain.size(); + // jointChain.dump(); + jointChain.outputRelativePoses(_poses); + } + + const float FRAMES_PER_SECOND = 30.0f; + _interpAlphaVel = FRAMES_PER_SECOND / _interpDuration; + _alpha = _interpAlphaVel * dt; // we need to blend the old joint chain with the current joint chain, otherwise known as: _snapShotChain + // we blend the chain info then we accumulate it then we assign to relative poses then we return the value. + // make the alpha + // make the prevchain + // interp from the previous chain to the new chain/or underposes if the ik is disabled. + // update the relative poses and then we are done + + /**/ return _poses; } @@ -162,14 +178,12 @@ void AnimSplineIK::solveTargetWithSpline(const AnimContext& context, const IKTar if (glm::dot(halfRot * Vectors::UNIT_Z, basePose.rot() * Vectors::UNIT_Z) < 0.0f) { tipPose.rot() = -tipPose.rot(); } - qCDebug(animation) << "spot 1"; // find or create splineJointInfo for this target const std::vector* splineJointInfoVec = findOrCreateSplineJointInfo(context, target); if (splineJointInfoVec && splineJointInfoVec->size() > 0) { const int baseParentIndex = _skeleton->getParentIndex(baseIndex); AnimPose parentAbsPose = (baseParentIndex >= 0) ? absolutePoses[baseParentIndex] : AnimPose(); - qCDebug(animation) << "spot 2"; // go thru splineJointInfoVec backwards (base to tip) for (int i = (int)splineJointInfoVec->size() - 1; i >= 0; i--) { const SplineJointInfo& splineJointInfo = (*splineJointInfoVec)[i]; diff --git a/libraries/animation/src/AnimStateMachine.cpp b/libraries/animation/src/AnimStateMachine.cpp index 3042ad20f0..2c5d4ad0f3 100644 --- a/libraries/animation/src/AnimStateMachine.cpp +++ b/libraries/animation/src/AnimStateMachine.cpp @@ -22,7 +22,6 @@ AnimStateMachine::~AnimStateMachine() { } const AnimPoseVec& AnimStateMachine::evaluate(const AnimVariantMap& animVars, const AnimContext& context, float dt, AnimVariantMap& triggersOut) { - qCDebug(animation) << "evaluating state machine"; float parentDebugAlpha = context.getDebugAlpha(_id); QString desiredStateID = animVars.lookup(_currentStateVar, _currentState->getID()); diff --git a/libraries/animation/src/AnimTwoBoneIK.cpp b/libraries/animation/src/AnimTwoBoneIK.cpp index d970e6b862..6334f6c4fd 100644 --- a/libraries/animation/src/AnimTwoBoneIK.cpp +++ b/libraries/animation/src/AnimTwoBoneIK.cpp @@ -46,8 +46,6 @@ AnimTwoBoneIK::~AnimTwoBoneIK() { const AnimPoseVec& AnimTwoBoneIK::evaluate(const AnimVariantMap& animVars, const AnimContext& context, float dt, AnimVariantMap& triggersOut) { - qCDebug(animation) << "evaluating the 2 bone IK"; - assert(_children.size() == 1); if (_children.size() != 1) { return _poses; diff --git a/libraries/fbx/src/FBXSerializer.cpp b/libraries/fbx/src/FBXSerializer.cpp index 68019c2f4b..5e7258f069 100644 --- a/libraries/fbx/src/FBXSerializer.cpp +++ b/libraries/fbx/src/FBXSerializer.cpp @@ -1308,6 +1308,7 @@ HFMModel* FBXSerializer::extractHFMModel(const QVariantHash& mapping, const QStr joint.inverseBindRotation = joint.inverseDefaultRotation; joint.name = fbxModel.name; if (hfmModel.hfmToHifiJointNameMapping.contains(hfmModel.hfmToHifiJointNameMapping.key(joint.name))) { + // qCDebug(modelformat) << "joint name " << joint.name << " hifi name " << hfmModel.hfmToHifiJointNameMapping.key(fbxModel.name); joint.name = hfmModel.hfmToHifiJointNameMapping.key(fbxModel.name); } From 777716235106b6d8c5efa34cec4ad8a841309b47 Mon Sep 17 00:00:00 2001 From: amantley Date: Fri, 18 Jan 2019 15:28:41 -0800 Subject: [PATCH 006/112] got the spine2 rotationa and the head spline working --- .../resources/avatar/avatar-animation.json | 18 ---- interface/src/Application.cpp | 2 +- interface/src/avatar/MySkeletonModel.cpp | 5 +- libraries/animation/src/AnimSplineIK.cpp | 86 +++++++++++++++++-- 4 files changed, 86 insertions(+), 25 deletions(-) diff --git a/interface/resources/avatar/avatar-animation.json b/interface/resources/avatar/avatar-animation.json index 16523afba3..f68d7e61d4 100644 --- a/interface/resources/avatar/avatar-animation.json +++ b/interface/resources/avatar/avatar-animation.json @@ -159,24 +159,6 @@ "poleVectorEnabledVar": "leftHandPoleVectorEnabled", "poleReferenceVectorVar": "leftHandPoleReferenceVector", "poleVectorVar": "leftHandPoleVector" - }, - { - "jointName": "Spine2", - "positionVar": "spine2Position", - "rotationVar": "spine2Rotation", - "typeVar": "spine2Type", - "weightVar": "spine2Weight", - "weight": 2.0, - "flexCoefficients": [ 1.0, 0.5, 0.25 ] - }, - { - "jointName": "Head", - "positionVar": "headPosition", - "rotationVar": "headRotation", - "typeVar": "spine2Type", - "weightVar": "headWeight", - "weight": 4.0, - "flexCoefficients": [ 1, 0.5, 0.25, 0.2, 0.1 ] } ] }, diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 2816dbcb04..2401bf5315 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -4679,7 +4679,7 @@ void setupCpuMonitorThread() { void Application::idle() { PerformanceTimer perfTimer("idle"); - + qCDebug(interfaceapp) << "idle called"; // Update the deadlock watchdog updateHeartbeat(); diff --git a/interface/src/avatar/MySkeletonModel.cpp b/interface/src/avatar/MySkeletonModel.cpp index 356b365f93..e0362ef548 100644 --- a/interface/src/avatar/MySkeletonModel.cpp +++ b/interface/src/avatar/MySkeletonModel.cpp @@ -199,7 +199,7 @@ void MySkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) { // if hips are not under direct control, estimate the hips position. if (avatarHeadPose.isValid() && !(params.primaryControllerFlags[Rig::PrimaryControllerType_Hips] & (uint8_t)Rig::ControllerFlags::Enabled)) { bool isFlying = (myAvatar->getCharacterController()->getState() == CharacterController::State::Hover || myAvatar->getCharacterController()->computeCollisionGroup() == BULLET_COLLISION_GROUP_COLLISIONLESS); - + // timescale in seconds const float TRANS_HORIZ_TIMESCALE = 0.15f; const float TRANS_VERT_TIMESCALE = 0.01f; // We want the vertical component of the hips to follow quickly to prevent spine squash/stretch. @@ -255,6 +255,9 @@ void MySkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) { AnimPose newSpinePose(glm::mat4(glm::vec4(w, 0.0f), glm::vec4(u, 0.0f), glm::vec4(v, 0.0f), glm::vec4(glm::vec3(0.0f, 0.0f, 0.0f), 1.0f))); currentSpine2Pose.rot() = safeLerp(currentSpine2Pose.rot(), newSpinePose.rot(), SPINE2_ROTATION_FILTER); params.primaryControllerPoses[Rig::PrimaryControllerType_Spine2] = currentSpine2Pose; + qCDebug(interfaceapp) << "finding the spine 2 azimuth"; + qCDebug(interfaceapp) << currentSpine2Pose; + params.primaryControllerFlags[Rig::PrimaryControllerType_Spine2] = (uint8_t)Rig::ControllerFlags::Enabled | (uint8_t)Rig::ControllerFlags::Estimated; } } diff --git a/libraries/animation/src/AnimSplineIK.cpp b/libraries/animation/src/AnimSplineIK.cpp index 442112e8f0..6f1c15d0f9 100644 --- a/libraries/animation/src/AnimSplineIK.cpp +++ b/libraries/animation/src/AnimSplineIK.cpp @@ -53,7 +53,21 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const AnimPoseVec absolutePoses; absolutePoses.resize(_poses.size()); computeAbsolutePoses(absolutePoses); + AnimPoseVec absolutePoses2; + absolutePoses2.resize(_poses.size()); + // do this later + computeAbsolutePoses(absolutePoses2); + int jointIndex2 = _skeleton->nameToJointIndex("Spine2"); + AnimPose origSpine2PoseAbs = _skeleton->getAbsolutePose(jointIndex2, _poses); + if ((jointIndex2 != -1) && (_poses.size() > 0)) { + AnimPose origSpine2 = _skeleton->getAbsolutePose(jointIndex2, _poses); + AnimPose origSpine1 = _skeleton->getAbsolutePose(_skeleton->nameToJointIndex("Spine1"),_poses); + //origSpine2PoseRel = origSpine1.inverse() * origSpine2; + //qCDebug(animation) << "origSpine2Pose: " << origSpine2Pose.rot(); + qCDebug(animation) << "original relative spine2 " << origSpine2PoseAbs; + } + IKTarget target; int jointIndex = _skeleton->nameToJointIndex("Head"); if (jointIndex != -1) { @@ -64,30 +78,92 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const glm::vec3 translation = animVars.lookupRigToGeometry("headPosition", absPose.trans()); float weight = animVars.lookup("headWeight", "4.0"); + //qCDebug(animation) << "target 1 rotation absolute" << rotation; target.setPose(rotation, translation); target.setWeight(weight); const float* flexCoefficients = new float[5]{ 1.0f, 0.5f, 0.25f, 0.2f, 0.1f }; - target.setFlexCoefficients(4, flexCoefficients); + target.setFlexCoefficients(5, flexCoefficients); // record the index of the hips ik target. if (target.getIndex() == _hipsIndex) { _hipsTargetIndex = 1; } } + + AnimPose origAbsAfterHeadSpline; + AnimPose finalSpine2; + AnimChain jointChain; if (_poses.size() > 0) { - AnimChain jointChain; + _snapshotChain.buildFromRelativePoses(_skeleton, _poses, target.getIndex()); jointChain.buildFromRelativePoses(_skeleton, _poses, target.getIndex()); + // jointChain2.buildFromRelativePoses(_skeleton, _poses, target2.getIndex()); // for each target solve target with spline + //qCDebug(animation) << "before head spline"; + //jointChain.dump(); solveTargetWithSpline(context, target, absolutePoses, false, jointChain); + AnimPose afterSolveSpine2 = jointChain.getAbsolutePoseFromJointIndex(jointIndex2); + AnimPose afterSolveSpine1 = jointChain.getAbsolutePoseFromJointIndex(_skeleton->nameToJointIndex("Spine1")); + AnimPose afterSolveSpine2Rel = afterSolveSpine1.inverse() * afterSolveSpine2; + AnimPose originalSpine2Relative = afterSolveSpine1.inverse() * origSpine2PoseAbs; + glm::quat rotation3 = animVars.lookupRigToGeometry("spine2Rotation", afterSolveSpine2.rot()); + glm::vec3 translation3 = animVars.lookupRigToGeometry("spine2Position", afterSolveSpine2.trans()); + AnimPose targetSpine2(rotation3, afterSolveSpine2.trans()); + finalSpine2 = afterSolveSpine1.inverse() * targetSpine2; - // qCDebug(animation) << "AnimSpline Joint chain length " << jointChain.size(); - // jointChain.dump(); + qCDebug(animation) << "relative spine2 after solve" << afterSolveSpine2Rel; + qCDebug(animation) << "relative spine2 orig" << originalSpine2Relative; + AnimPose latestSpine2Relative(originalSpine2Relative.rot(), afterSolveSpine2Rel.trans()); + //jointChain.setRelativePoseAtJointIndex(jointIndex2, finalSpine2); jointChain.outputRelativePoses(_poses); + //qCDebug(animation) << "after head spline"; + //jointChain.dump(); + + //computeAbsolutePoses(absolutePoses2); + origAbsAfterHeadSpline = _skeleton->getAbsolutePose(jointIndex2, _poses); + // qCDebug(animation) << "Spine2 trans after head spline: " << origAbsAfterHeadSpline.trans(); + + } + + IKTarget target2; + //int jointIndex2 = _skeleton->nameToJointIndex("Spine2"); + if (jointIndex2 != -1) { + target2.setType(animVars.lookup("spine2Type", (int)IKTarget::Type::RotationAndPosition)); + target2.setIndex(jointIndex2); + AnimPose absPose2 = _skeleton->getAbsolutePose(jointIndex2, _poses); + glm::quat rotation2 = animVars.lookupRigToGeometry("spine2Rotation", absPose2.rot()); + glm::vec3 translation2 = animVars.lookupRigToGeometry("spine2Position", absPose2.trans()); + float weight2 = animVars.lookup("spine2Weight", "2.0"); + qCDebug(animation) << "rig to geometry" << rotation2; + + target2.setPose(rotation2, translation2); + target2.setPose(finalSpine2.rot(), finalSpine2.trans()); + target2.setWeight(weight2); + const float* flexCoefficients2 = new float[3]{ 1.0f, 0.5f, 0.25f }; + target2.setFlexCoefficients(3, flexCoefficients2); + + + } + AnimChain jointChain2; + if (_poses.size() > 0) { + + // _snapshotChain.buildFromRelativePoses(_skeleton, _poses, target.getIndex()); + // jointChain.buildFromRelativePoses(_skeleton, _poses, target.getIndex()); + // jointChain2.buildFromRelativePoses(_skeleton, underPoses, target2.getIndex()); + jointChain2.buildFromRelativePoses(_skeleton, _poses, target2.getIndex()); + + // for each target solve target with spline + solveTargetWithSpline(context, target2, absolutePoses2, false, jointChain2); + + //jointChain.outputRelativePoses(_poses); + jointChain2.outputRelativePoses(_poses); + //qCDebug(animation) << "Spine2 spline"; + //jointChain2.dump(); + //qCDebug(animation) << "Spine2Pose trans after spine2 spline: " << _skeleton->getAbsolutePose(jointIndex2, _poses).trans(); } - + const float FRAMES_PER_SECOND = 30.0f; _interpAlphaVel = FRAMES_PER_SECOND / _interpDuration; _alpha = _interpAlphaVel * dt; From 4a6d5e418730f54da54ede95a0adef94ca3dade4 Mon Sep 17 00:00:00 2001 From: amantley Date: Fri, 18 Jan 2019 15:50:29 -0800 Subject: [PATCH 007/112] both head and spine2 spline to working in consecutive order --- libraries/animation/src/AnimSplineIK.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/libraries/animation/src/AnimSplineIK.cpp b/libraries/animation/src/AnimSplineIK.cpp index 6f1c15d0f9..79a1a431c8 100644 --- a/libraries/animation/src/AnimSplineIK.cpp +++ b/libraries/animation/src/AnimSplineIK.cpp @@ -56,7 +56,7 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const AnimPoseVec absolutePoses2; absolutePoses2.resize(_poses.size()); // do this later - computeAbsolutePoses(absolutePoses2); + // computeAbsolutePoses(absolutePoses2); int jointIndex2 = _skeleton->nameToJointIndex("Spine2"); AnimPose origSpine2PoseAbs = _skeleton->getAbsolutePose(jointIndex2, _poses); @@ -93,6 +93,7 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const AnimPose origAbsAfterHeadSpline; AnimPose finalSpine2; AnimChain jointChain; + AnimPose targetSpine2; if (_poses.size() > 0) { _snapshotChain.buildFromRelativePoses(_skeleton, _poses, target.getIndex()); @@ -109,7 +110,7 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const AnimPose originalSpine2Relative = afterSolveSpine1.inverse() * origSpine2PoseAbs; glm::quat rotation3 = animVars.lookupRigToGeometry("spine2Rotation", afterSolveSpine2.rot()); glm::vec3 translation3 = animVars.lookupRigToGeometry("spine2Position", afterSolveSpine2.trans()); - AnimPose targetSpine2(rotation3, afterSolveSpine2.trans()); + targetSpine2 = AnimPose(rotation3, afterSolveSpine2.trans()); finalSpine2 = afterSolveSpine1.inverse() * targetSpine2; qCDebug(animation) << "relative spine2 after solve" << afterSolveSpine2Rel; @@ -120,7 +121,7 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const //qCDebug(animation) << "after head spline"; //jointChain.dump(); - //computeAbsolutePoses(absolutePoses2); + computeAbsolutePoses(absolutePoses2); origAbsAfterHeadSpline = _skeleton->getAbsolutePose(jointIndex2, _poses); // qCDebug(animation) << "Spine2 trans after head spline: " << origAbsAfterHeadSpline.trans(); @@ -137,8 +138,8 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const float weight2 = animVars.lookup("spine2Weight", "2.0"); qCDebug(animation) << "rig to geometry" << rotation2; - target2.setPose(rotation2, translation2); - target2.setPose(finalSpine2.rot(), finalSpine2.trans()); + //target2.setPose(rotation2, translation2); + target2.setPose(targetSpine2.rot(), targetSpine2.trans()); target2.setWeight(weight2); const float* flexCoefficients2 = new float[3]{ 1.0f, 0.5f, 0.25f }; target2.setFlexCoefficients(3, flexCoefficients2); From 7115796fc42db231fb6445a473663800bfab3bae Mon Sep 17 00:00:00 2001 From: amantley Date: Fri, 18 Jan 2019 16:47:55 -0800 Subject: [PATCH 008/112] version with spline from Spine2 to head --- libraries/animation/src/AnimChain.h | 10 ++ libraries/animation/src/AnimSplineIK.cpp | 127 ++++++++++++++--------- libraries/animation/src/AnimSplineIK.h | 13 +-- 3 files changed, 96 insertions(+), 54 deletions(-) diff --git a/libraries/animation/src/AnimChain.h b/libraries/animation/src/AnimChain.h index 2385e0c16a..37d175a334 100644 --- a/libraries/animation/src/AnimChain.h +++ b/libraries/animation/src/AnimChain.h @@ -82,6 +82,16 @@ public: return foundIndex; } + const AnimPose& getRelativePoseAtJointIndex(int jointIndex) const { + for (int i = 0; i < _top; i++) { + if (_chain[i].jointIndex == jointIndex) { + return _chain[i].relativePose; + } + } + return AnimPose::identity; + } + + void buildDirtyAbsolutePoses() { // the relative and absolute pose is the same for the base of the chain. _chain[_top - 1].absolutePose = _chain[_top - 1].relativePose; diff --git a/libraries/animation/src/AnimSplineIK.cpp b/libraries/animation/src/AnimSplineIK.cpp index 79a1a431c8..d55484f7c7 100644 --- a/libraries/animation/src/AnimSplineIK.cpp +++ b/libraries/animation/src/AnimSplineIK.cpp @@ -52,11 +52,11 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const // check to see if we actually need absolute poses. AnimPoseVec absolutePoses; absolutePoses.resize(_poses.size()); - computeAbsolutePoses(absolutePoses); + //computeAbsolutePoses(absolutePoses); AnimPoseVec absolutePoses2; absolutePoses2.resize(_poses.size()); // do this later - // computeAbsolutePoses(absolutePoses2); + computeAbsolutePoses(absolutePoses2); int jointIndex2 = _skeleton->nameToJointIndex("Spine2"); AnimPose origSpine2PoseAbs = _skeleton->getAbsolutePose(jointIndex2, _poses); @@ -67,6 +67,45 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const //qCDebug(animation) << "origSpine2Pose: " << origSpine2Pose.rot(); qCDebug(animation) << "original relative spine2 " << origSpine2PoseAbs; } + + IKTarget target2; + //int jointIndex2 = _skeleton->nameToJointIndex("Spine2"); + if (jointIndex2 != -1) { + target2.setType(animVars.lookup("spine2Type", (int)IKTarget::Type::RotationAndPosition)); + target2.setIndex(jointIndex2); + AnimPose absPose2 = _skeleton->getAbsolutePose(jointIndex2, _poses); + glm::quat rotation2 = animVars.lookupRigToGeometry("spine2Rotation", absPose2.rot()); + glm::vec3 translation2 = animVars.lookupRigToGeometry("spine2Position", absPose2.trans()); + float weight2 = animVars.lookup("spine2Weight", "2.0"); + qCDebug(animation) << "rig to geometry" << rotation2; + + target2.setPose(rotation2, translation2); + //target2.setPose(targetSpine2.rot(), targetSpine2.trans()); + target2.setWeight(weight2); + const float* flexCoefficients2 = new float[3]{ 1.0f, 0.5f, 0.25f }; + target2.setFlexCoefficients(3, flexCoefficients2); + + + } + AnimChain jointChain2; + if (_poses.size() > 0) { + + // _snapshotChain.buildFromRelativePoses(_skeleton, _poses, target.getIndex()); + // jointChain.buildFromRelativePoses(_skeleton, _poses, target.getIndex()); + // jointChain2.buildFromRelativePoses(_skeleton, underPoses, target2.getIndex()); + jointChain2.buildFromRelativePoses(_skeleton, _poses, target2.getIndex()); + + // for each target solve target with spline + solveTargetWithSpline(context, target2, absolutePoses2, false, jointChain2); + + //jointChain.outputRelativePoses(_poses); + jointChain2.outputRelativePoses(_poses); + computeAbsolutePoses(absolutePoses); + //qCDebug(animation) << "Spine2 spline"; + //jointChain2.dump(); + //qCDebug(animation) << "Spine2Pose trans after spine2 spline: " << _skeleton->getAbsolutePose(jointIndex2, _poses).trans(); + + } IKTarget target; int jointIndex = _skeleton->nameToJointIndex("Head"); @@ -81,8 +120,9 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const //qCDebug(animation) << "target 1 rotation absolute" << rotation; target.setPose(rotation, translation); target.setWeight(weight); - const float* flexCoefficients = new float[5]{ 1.0f, 0.5f, 0.25f, 0.2f, 0.1f }; - target.setFlexCoefficients(5, flexCoefficients); + //const float* flexCoefficients = new float[5]{ 1.0f, 0.5f, 0.25f, 0.2f, 0.1f }; + const float* flexCoefficients = new float[2]{ 1.0f, 0.5f }; + target.setFlexCoefficients(2, flexCoefficients); // record the index of the hips ik target. if (target.getIndex() == _hipsIndex) { @@ -118,52 +158,23 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const AnimPose latestSpine2Relative(originalSpine2Relative.rot(), afterSolveSpine2Rel.trans()); //jointChain.setRelativePoseAtJointIndex(jointIndex2, finalSpine2); jointChain.outputRelativePoses(_poses); + _poses[_headIndex] = jointChain.getRelativePoseAtJointIndex(_headIndex); + _poses[_skeleton->nameToJointIndex("Neck")] = jointChain.getRelativePoseAtJointIndex(_skeleton->nameToJointIndex("Neck")); + _poses[_spine2Index] = jointChain.getRelativePoseAtJointIndex(_spine2Index); + + //custom output code for the head. just do the head neck and spine2 + + //qCDebug(animation) << "after head spline"; //jointChain.dump(); - computeAbsolutePoses(absolutePoses2); - origAbsAfterHeadSpline = _skeleton->getAbsolutePose(jointIndex2, _poses); + //computeAbsolutePoses(absolutePoses2); + //origAbsAfterHeadSpline = _skeleton->getAbsolutePose(jointIndex2, _poses); // qCDebug(animation) << "Spine2 trans after head spline: " << origAbsAfterHeadSpline.trans(); } - IKTarget target2; - //int jointIndex2 = _skeleton->nameToJointIndex("Spine2"); - if (jointIndex2 != -1) { - target2.setType(animVars.lookup("spine2Type", (int)IKTarget::Type::RotationAndPosition)); - target2.setIndex(jointIndex2); - AnimPose absPose2 = _skeleton->getAbsolutePose(jointIndex2, _poses); - glm::quat rotation2 = animVars.lookupRigToGeometry("spine2Rotation", absPose2.rot()); - glm::vec3 translation2 = animVars.lookupRigToGeometry("spine2Position", absPose2.trans()); - float weight2 = animVars.lookup("spine2Weight", "2.0"); - qCDebug(animation) << "rig to geometry" << rotation2; - - //target2.setPose(rotation2, translation2); - target2.setPose(targetSpine2.rot(), targetSpine2.trans()); - target2.setWeight(weight2); - const float* flexCoefficients2 = new float[3]{ 1.0f, 0.5f, 0.25f }; - target2.setFlexCoefficients(3, flexCoefficients2); - - - } - AnimChain jointChain2; - if (_poses.size() > 0) { - - // _snapshotChain.buildFromRelativePoses(_skeleton, _poses, target.getIndex()); - // jointChain.buildFromRelativePoses(_skeleton, _poses, target.getIndex()); - // jointChain2.buildFromRelativePoses(_skeleton, underPoses, target2.getIndex()); - jointChain2.buildFromRelativePoses(_skeleton, _poses, target2.getIndex()); - - // for each target solve target with spline - solveTargetWithSpline(context, target2, absolutePoses2, false, jointChain2); - - //jointChain.outputRelativePoses(_poses); - jointChain2.outputRelativePoses(_poses); - //qCDebug(animation) << "Spine2 spline"; - //jointChain2.dump(); - //qCDebug(animation) << "Spine2Pose trans after spine2 spline: " << _skeleton->getAbsolutePose(jointIndex2, _poses).trans(); - - } + const float FRAMES_PER_SECOND = 30.0f; _interpAlphaVel = FRAMES_PER_SECOND / _interpDuration; @@ -218,6 +229,7 @@ void AnimSplineIK::setSkeletonInternal(AnimSkeleton::ConstPointer skeleton) { AnimNode::setSkeletonInternal(skeleton); _headIndex = _skeleton->nameToJointIndex("Head"); _hipsIndex = _skeleton->nameToJointIndex("Hips"); + _spine2Index = _skeleton->nameToJointIndex("Spine2"); lookUpIndices(); } @@ -234,16 +246,24 @@ static CubicHermiteSplineFunctorWithArcLength computeSplineFromTipAndBase(const void AnimSplineIK::solveTargetWithSpline(const AnimContext& context, const IKTarget& target, const AnimPoseVec& absolutePoses, bool debug, AnimChain& chainInfoOut) const { const int baseIndex = _hipsIndex; + const int headBaseIndex = _spine2Index; // build spline from tip to base AnimPose tipPose = AnimPose(glm::vec3(1.0f), target.getRotation(), target.getTranslation()); - AnimPose basePose = absolutePoses[baseIndex]; + AnimPose basePose; + if (target.getIndex() == _headIndex) { + basePose = absolutePoses[headBaseIndex]; + } else { + basePose = absolutePoses[baseIndex]; + } + CubicHermiteSplineFunctorWithArcLength spline; if (target.getIndex() == _headIndex) { // set gain factors so that more curvature occurs near the tip of the spline. const float HIPS_GAIN = 0.5f; const float HEAD_GAIN = 1.0f; - spline = computeSplineFromTipAndBase(tipPose, basePose, HIPS_GAIN, HEAD_GAIN); + //spline = computeSplineFromTipAndBase(tipPose, basePose, HIPS_GAIN, HEAD_GAIN); + spline = computeSplineFromTipAndBase(tipPose, basePose); } else { spline = computeSplineFromTipAndBase(tipPose, basePose); } @@ -347,14 +367,20 @@ void AnimSplineIK::computeAndCacheSplineJointInfosForIKTarget(const AnimContext& // build spline between the default poses. AnimPose tipPose = _skeleton->getAbsoluteDefaultPose(target.getIndex()); - AnimPose basePose = _skeleton->getAbsoluteDefaultPose(_hipsIndex); + AnimPose basePose; + if (target.getIndex() == _headIndex) { + basePose = _skeleton->getAbsoluteDefaultPose(_spine2Index); + } else { + basePose = _skeleton->getAbsoluteDefaultPose(_hipsIndex); + } CubicHermiteSplineFunctorWithArcLength spline; if (target.getIndex() == _headIndex) { // set gain factors so that more curvature occurs near the tip of the spline. const float HIPS_GAIN = 0.5f; const float HEAD_GAIN = 1.0f; - spline = computeSplineFromTipAndBase(tipPose, basePose, HIPS_GAIN, HEAD_GAIN); + // spline = computeSplineFromTipAndBase(tipPose, basePose, HIPS_GAIN, HEAD_GAIN); + spline = computeSplineFromTipAndBase(tipPose, basePose); } else { spline = computeSplineFromTipAndBase(tipPose, basePose); } @@ -367,7 +393,12 @@ void AnimSplineIK::computeAndCacheSplineJointInfosForIKTarget(const AnimContext& glm::vec3 baseToTipNormal = baseToTip / baseToTipLength; int index = target.getIndex(); - int endIndex = _skeleton->getParentIndex(_hipsIndex); + int endIndex; + if (target.getIndex() == _headIndex) { + endIndex = _skeleton->getParentIndex(_spine2Index); + } else { + endIndex = _skeleton->getParentIndex(_hipsIndex); + } while (index != endIndex) { AnimPose defaultPose = _skeleton->getAbsoluteDefaultPose(index); diff --git a/libraries/animation/src/AnimSplineIK.h b/libraries/animation/src/AnimSplineIK.h index 79f012365a..d303f81053 100644 --- a/libraries/animation/src/AnimSplineIK.h +++ b/libraries/animation/src/AnimSplineIK.h @@ -51,12 +51,13 @@ protected: QString _baseJointName; QString _tipJointName; - int _baseParentJointIndex{ -1 }; - int _baseJointIndex{ -1 }; - int _tipJointIndex{ -1 }; - int _headIndex{ -1 }; - int _hipsIndex{ -1 }; - int _hipsTargetIndex{ -1 }; + int _baseParentJointIndex { -1 }; + int _baseJointIndex { -1 }; + int _tipJointIndex { -1 }; + int _headIndex { -1 }; + int _hipsIndex { -1 }; + int _spine2Index { -1 }; + int _hipsTargetIndex { -1 }; QString _alphaVar; // float - (0, 1) 0 means underPoses only, 1 means IK only. QString _enabledVar; // bool From 3a2697fa8c3a69f80416988e88f818989adadaab Mon Sep 17 00:00:00 2001 From: amantley Date: Fri, 18 Jan 2019 17:55:19 -0800 Subject: [PATCH 009/112] working on the two bone ik for the hands --- .../avatar/avatar-animation_twoboneIK.json | 2213 +++++++++++++++++ libraries/animation/src/AnimSplineIK.cpp | 94 +- 2 files changed, 2262 insertions(+), 45 deletions(-) create mode 100644 interface/resources/avatar/avatar-animation_twoboneIK.json diff --git a/interface/resources/avatar/avatar-animation_twoboneIK.json b/interface/resources/avatar/avatar-animation_twoboneIK.json new file mode 100644 index 0000000000..ba84a5d527 --- /dev/null +++ b/interface/resources/avatar/avatar-animation_twoboneIK.json @@ -0,0 +1,2213 @@ +{ + "version": "1.1", + "root": { + "id": "userAnimStateMachine", + "type": "stateMachine", + "data": { + "currentState": "userAnimNone", + "states": [ + { + "id": "userAnimNone", + "interpTarget": 6, + "interpDuration": 6, + "transitions": [ + { "var": "userAnimA", "state": "userAnimA" }, + { "var": "userAnimB", "state": "userAnimB" } + ] + }, + { + "id": "userAnimA", + "interpTarget": 6, + "interpDuration": 6, + "transitions": [ + { "var": "userAnimNone", "state": "userAnimNone" }, + { "var": "userAnimB", "state": "userAnimB" } + ] + }, + { + "id": "userAnimB", + "interpTarget": 6, + "interpDuration": 6, + "transitions": [ + { "var": "userAnimNone", "state": "userAnimNone" }, + { "var": "userAnimA", "state": "userAnimA" } + ] + } + ] + }, + "children": [ + { + "id": "userAnimNone", + "type": "splineIK", + "data": { + "alpha": 1.0, + "enabled": false, + "interpDuration": 15, + "baseJointName": "Hips", + "tipJointName": "Head", + "alphaVar": "splineIKAlpha", + "enabledVar": "splineIKEnabled", + "endEffectorRotationVarVar": "splineIKRotationVar", + "endEffectorPositionVarVar": "splineIKPositionVar" + }, + "children": [ + { + "id": "rightFootPoleVector", + "type": "poleVectorConstraint", + "data": { + "enabled": false, + "referenceVector": [ 0, 0, 1 ], + "baseJointName": "RightUpLeg", + "midJointName": "RightLeg", + "tipJointName": "RightFoot", + "enabledVar": "rightFootPoleVectorEnabled", + "poleVectorVar": "rightFootPoleVector" + }, + "children": [ + { + "id": "rightFootIK", + "type": "twoBoneIK", + "data": { + "alpha": 1.0, + "enabled": false, + "interpDuration": 15, + "baseJointName": "RightUpLeg", + "midJointName": "RightLeg", + "tipJointName": "RightFoot", + "midHingeAxis": [ -1, 0, 0 ], + "alphaVar": "rightFootIKAlpha", + "enabledVar": "rightFootIKEnabled", + "endEffectorRotationVarVar": "rightFootIKRotationVar", + "endEffectorPositionVarVar": "rightFootIKPositionVar" + }, + "children": [ + { + "id": "leftFootPoleVector", + "type": "poleVectorConstraint", + "data": { + "enabled": false, + "referenceVector": [ 0, 0, 1 ], + "baseJointName": "LeftUpLeg", + "midJointName": "LeftLeg", + "tipJointName": "LeftFoot", + "enabledVar": "leftFootPoleVectorEnabled", + "poleVectorVar": "leftFootPoleVector" + }, + "children": [ + { + "id": "leftFootIK", + "type": "twoBoneIK", + "data": { + "alpha": 1.0, + "enabled": false, + "interpDuration": 15, + "baseJointName": "LeftUpLeg", + "midJointName": "LeftLeg", + "tipJointName": "LeftFoot", + "midHingeAxis": [ -1, 0, 0 ], + "alphaVar": "leftFootIKAlpha", + "enabledVar": "leftFootIKEnabled", + "endEffectorRotationVarVar": "leftFootIKRotationVar", + "endEffectorPositionVarVar": "leftFootIKPositionVar" + }, + "children": [ + { + "id": "rightArmPoleVector", + "type": "poleVectorConstraint", + "data": { + "enabled": false, + "referenceVector": [ 0, 0, 1 ], + "baseJointName": "RightArm", + "midJointName": "RightForeArm", + "tipJointName": "RightHand", + "enabledVar": "rightHandPoleVectorEnabled", + "poleVectorVar": "rightHandPoleVector" + }, + "children": [ + { + "id": "rightArmIK", + "type": "twoBoneIK", + "data": { + "alpha": 1.0, + "enabled": false, + "interpDuration": 15, + "baseJointName": "RightArm", + "midJointName": "RightForeArm", + "tipJointName": "RightHand", + "midHingeAxis": [ 1, 0, 0 ], + "alphaVar": "rightArmIKAlpha", + "enabledVar": "rightArmIKEnabled", + "endEffectorRotationVarVar": "rightArmIKRotationVar", + "endEffectorPositionVarVar": "rightArmIKPositionVar" + }, + "children": [ + { + "id": "ikOverlay", + "type": "overlay", + "data": { + "alpha": 1.0, + "alphaVar": "ikOverlayAlpha", + "boneSet": "fullBody" + }, + "children": [ + { + "id": "ik", + "type": "inverseKinematics", + "data": { + "solutionSource": "relaxToUnderPoses", + "solutionSourceVar": "solutionSource", + "targets": [ + { + "jointName": "Hips", + "positionVar": "hipsPosition", + "rotationVar": "hipsRotation", + "typeVar": "hipsType", + "weightVar": "hipsWeight", + "weight": 1.0, + "flexCoefficients": [ 1 ] + }, + { + "jointName": "LeftHand", + "positionVar": "leftHandPosition", + "rotationVar": "leftHandRotation", + "typeVar": "leftHandType", + "weightVar": "leftHandWeight", + "weight": 1.0, + "flexCoefficients": [ 1, 0.5, 0.5, 0.2, 0.01, 0.005, 0.001, 0.0, 0.0 ], + "poleVectorEnabledVar": "leftHandPoleVectorEnabled", + "poleReferenceVectorVar": "leftHandPoleReferenceVector", + "poleVectorVar": "leftHandPoleVector" + } + ] + }, + "children": [] + }, + { + "id": "defaultPoseOverlay", + "type": "overlay", + "data": { + "alpha": 0.0, + "alphaVar": "defaultPoseOverlayAlpha", + "boneSet": "fullBody", + "boneSetVar": "defaultPoseOverlayBoneSet" + }, + "children": [ + { + "id": "defaultPose", + "type": "defaultPose", + "data": { + }, + "children": [] + }, + { + "id": "rightHandOverlay", + "type": "overlay", + "data": { + "alpha": 0.0, + "boneSet": "rightHand", + "alphaVar": "rightHandOverlayAlpha" + }, + "children": [ + { + "id": "rightHandStateMachine", + "type": "stateMachine", + "data": { + "currentState": "rightHandGrasp", + "states": [ + { + "id": "rightHandGrasp", + "interpTarget": 3, + "interpDuration": 3, + "transitions": [ + { + "var": "isRightIndexPoint", + "state": "rightIndexPoint" + }, + { + "var": "isRightThumbRaise", + "state": "rightThumbRaise" + }, + { + "var": "isRightIndexPointAndThumbRaise", + "state": "rightIndexPointAndThumbRaise" + } + ] + }, + { + "id": "rightIndexPoint", + "interpTarget": 15, + "interpDuration": 3, + "transitions": [ + { + "var": "isRightHandGrasp", + "state": "rightHandGrasp" + }, + { + "var": "isRightThumbRaise", + "state": "rightThumbRaise" + }, + { + "var": "isRightIndexPointAndThumbRaise", + "state": "rightIndexPointAndThumbRaise" + } + ] + }, + { + "id": "rightThumbRaise", + "interpTarget": 15, + "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" + } + ] + } + ] + }, + "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", + "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": "mainStateMachine", + "type": "stateMachine", + "data": { + "outputJoints": [ "LeftFoot", "RightFoot" ], + "currentState": "idle", + "states": [ + { + "id": "idle", + "interpTarget": 20, + "interpDuration": 8, + "interpType": "snapshotPrev", + "transitions": [ + { + "var": "isMovingForward", + "state": "WALKFWD" + }, + { + "var": "isMovingBackward", + "state": "WALKBWD" + }, + { + "var": "isMovingRight", + "state": "STRAFERIGHT" + }, + { + "var": "isMovingLeft", + "state": "STRAFELEFT" + }, + { + "var": "isTurningRight", + "state": "turnRight" + }, + { + "var": "isTurningLeft", + "state": "turnLeft" + }, + { + "var": "isFlying", + "state": "fly" + }, + { + "var": "isTakeoffStand", + "state": "takeoffStand" + }, + { + "var": "isTakeoffRun", + "state": "TAKEOFFRUN" + }, + { + "var": "isInAirStand", + "state": "inAirStand" + }, + { + "var": "isInAirRun", + "state": "INAIRRUN" + }, + { + "var": "isMovingRightHmd", + "state": "strafeRightHmd" + }, + { + "var": "isMovingLeftHmd", + "state": "strafeLeftHmd" + } + ] + }, + { + "id": "idleToWalkFwd", + "interpTarget": 12, + "interpDuration": 8, + "transitions": [ + { + "var": "idleToWalkFwdOnDone", + "state": "WALKFWD" + }, + { + "var": "isNotMoving", + "state": "idle" + }, + { + "var": "isMovingBackward", + "state": "WALKBWD" + }, + { + "var": "isMovingRight", + "state": "STRAFERIGHT" + }, + { + "var": "isMovingLeft", + "state": "STRAFELEFT" + }, + { + "var": "isTurningRight", + "state": "turnRight" + }, + { + "var": "isTurningLeft", + "state": "turnLeft" + }, + { + "var": "isFlying", + "state": "fly" + }, + { + "var": "isTakeoffStand", + "state": "takeoffStand" + }, + { + "var": "isTakeoffRun", + "state": "TAKEOFFRUN" + }, + { + "var": "isInAirStand", + "state": "inAirStand" + }, + { + "var": "isInAirRun", + "state": "INAIRRUN" + }, + { + "var": "isMovingRightHmd", + "state": "strafeRightHmd" + }, + { + "var": "isMovingLeftHmd", + "state": "strafeLeftHmd" + } + ] + }, + { + "id": "idleSettle", + "interpTarget": 15, + "interpDuration": 8, + "interpType": "snapshotPrev", + "transitions": [ + { + "var": "idleSettleOnDone", + "state": "idle" + }, + { + "var": "isMovingForward", + "state": "WALKFWD" + }, + { + "var": "isMovingBackward", + "state": "WALKBWD" + }, + { + "var": "isMovingRight", + "state": "STRAFERIGHT" + }, + { + "var": "isMovingLeft", + "state": "STRAFELEFT" + }, + { + "var": "isMovingRightHmd", + "state": "strafeRightHmd" + }, + { + "var": "isMovingLeftHmd", + "state": "strafeLeftHmd" + }, + { + "var": "isTurningRight", + "state": "turnRight" + }, + { + "var": "isTurningLeft", + "state": "turnLeft" + }, + { + "var": "isFlying", + "state": "fly" + }, + { + "var": "isTakeoffStand", + "state": "takeoffStand" + }, + { + "var": "isTakeoffRun", + "state": "TAKEOFFRUN" + }, + { + "var": "isInAirStand", + "state": "inAirStand" + }, + { + "var": "isInAirRun", + "state": "INAIRRUN" + } + ] + }, + { + "id": "WALKFWD", + "interpTarget": 35, + "interpDuration": 10, + "interpType": "snapshotPrev", + "transitions": [ + { + "var": "isNotMoving", + "state": "idleSettle" + }, + { + "var": "isMovingBackward", + "state": "WALKBWD" + }, + { + "var": "isMovingRight", + "state": "STRAFERIGHT" + }, + { + "var": "isMovingLeft", + "state": "STRAFELEFT" + }, + { + "var": "isTurningRight", + "state": "turnRight" + }, + { + "var": "isTurningLeft", + "state": "turnLeft" + }, + { + "var": "isFlying", + "state": "fly" + }, + { + "var": "isTakeoffStand", + "state": "takeoffStand" + }, + { + "var": "isTakeoffRun", + "state": "TAKEOFFRUN" + }, + { + "var": "isInAirStand", + "state": "inAirStand" + }, + { + "var": "isInAirRun", + "state": "INAIRRUN" + }, + { + "var": "isMovingRightHmd", + "state": "strafeRightHmd" + }, + { + "var": "isMovingLeftHmd", + "state": "strafeLeftHmd" + } + ] + }, + { + "id": "WALKBWD", + "interpTarget": 35, + "interpDuration": 10, + "interpType": "snapshotPrev", + "transitions": [ + { + "var": "isNotMoving", + "state": "idleSettle" + }, + { + "var": "isMovingForward", + "state": "WALKFWD" + }, + { + "var": "isMovingRight", + "state": "STRAFERIGHT" + }, + { + "var": "isMovingLeft", + "state": "STRAFELEFT" + }, + { + "var": "isTurningRight", + "state": "turnRight" + }, + { + "var": "isTurningLeft", + "state": "turnLeft" + }, + { + "var": "isFlying", + "state": "fly" + }, + { + "var": "isTakeoffStand", + "state": "takeoffStand" + }, + { + "var": "isTakeoffRun", + "state": "TAKEOFFRUN" + }, + { + "var": "isInAirStand", + "state": "inAirStand" + }, + { + "var": "isInAirRun", + "state": "INAIRRUN" + }, + { + "var": "isMovingRightHmd", + "state": "strafeRightHmd" + }, + { + "var": "isMovingLeftHmd", + "state": "strafeLeftHmd" + } + ] + }, + { + "id": "STRAFERIGHT", + "interpTarget": 25, + "interpDuration": 8, + "interpType": "snapshotPrev", + "transitions": [ + { + "var": "isNotMoving", + "state": "idleSettle" + }, + { + "var": "isMovingForward", + "state": "WALKFWD" + }, + { + "var": "isMovingBackward", + "state": "WALKBWD" + }, + { + "var": "isMovingLeft", + "state": "STRAFELEFT" + }, + { + "var": "isTurningRight", + "state": "turnRight" + }, + { + "var": "isTurningLeft", + "state": "turnLeft" + }, + { + "var": "isFlying", + "state": "fly" + }, + { + "var": "isTakeoffStand", + "state": "takeoffStand" + }, + { + "var": "isTakeoffRun", + "state": "TAKEOFFRUN" + }, + { + "var": "isInAirStand", + "state": "inAirStand" + }, + { + "var": "isInAirRun", + "state": "INAIRRUN" + }, + { + "var": "isMovingRightHmd", + "state": "strafeRightHmd" + }, + { + "var": "isMovingLeftHmd", + "state": "strafeLeftHmd" + } + ] + }, + { + "id": "STRAFELEFT", + "interpTarget": 25, + "interpDuration": 8, + "interpType": "snapshotPrev", + "transitions": [ + { + "var": "isNotMoving", + "state": "idleSettle" + }, + { + "var": "isMovingForward", + "state": "WALKFWD" + }, + { + "var": "isMovingBackward", + "state": "WALKBWD" + }, + { + "var": "isMovingRight", + "state": "STRAFERIGHT" + }, + { + "var": "isTurningRight", + "state": "turnRight" + }, + { + "var": "isTurningLeft", + "state": "turnLeft" + }, + { + "var": "isFlying", + "state": "fly" + }, + { + "var": "isTakeoffStand", + "state": "takeoffStand" + }, + { + "var": "isTakeoffRun", + "state": "TAKEOFFRUN" + }, + { + "var": "isInAirStand", + "state": "inAirStand" + }, + { + "var": "isInAirRun", + "state": "INAIRRUN" + }, + { + "var": "isMovingRightHmd", + "state": "strafeRightHmd" + }, + { + "var": "isMovingLeftHmd", + "state": "strafeLeftHmd" + } + ] + }, + { + "id": "turnRight", + "interpTarget": 6, + "interpDuration": 8, + "transitions": [ + { + "var": "isNotTurning", + "state": "idle" + }, + { + "var": "isMovingForward", + "state": "WALKFWD" + }, + { + "var": "isMovingBackward", + "state": "WALKBWD" + }, + { + "var": "isMovingRight", + "state": "STRAFERIGHT" + }, + { + "var": "isMovingLeft", + "state": "STRAFELEFT" + }, + { + "var": "isTurningLeft", + "state": "turnLeft" + }, + { + "var": "isFlying", + "state": "fly" + }, + { + "var": "isTakeoffStand", + "state": "takeoffStand" + }, + { + "var": "isTakeoffRun", + "state": "TAKEOFFRUN" + }, + { + "var": "isInAirStand", + "state": "inAirStand" + }, + { + "var": "isInAirRun", + "state": "INAIRRUN" + }, + { + "var": "isMovingRightHmd", + "state": "strafeRightHmd" + }, + { + "var": "isMovingLeftHmd", + "state": "strafeLeftHmd" + } + ] + }, + { + "id": "turnLeft", + "interpTarget": 6, + "interpDuration": 8, + "transitions": [ + { + "var": "isNotTurning", + "state": "idle" + }, + { + "var": "isMovingForward", + "state": "WALKFWD" + }, + { + "var": "isMovingBackward", + "state": "WALKBWD" + }, + { + "var": "isMovingRight", + "state": "STRAFERIGHT" + }, + { + "var": "isMovingLeft", + "state": "STRAFELEFT" + }, + { + "var": "isTurningRight", + "state": "turnRight" + }, + { + "var": "isFlying", + "state": "fly" + }, + { + "var": "isTakeoffStand", + "state": "takeoffStand" + }, + { + "var": "isTakeoffRun", + "state": "TAKEOFFRUN" + }, + { + "var": "isInAirStand", + "state": "inAirStand" + }, + { + "var": "isInAirRun", + "state": "INAIRRUN" + }, + { + "var": "isMovingRightHmd", + "state": "strafeRightHmd" + }, + { + "var": "isMovingLeftHmd", + "state": "strafeLeftHmd" + } + ] + }, + { + "id": "strafeRightHmd", + "interpTarget": 5, + "interpDuration": 8, + "interpType": "snapshotPrev", + "transitions": [ + { + "var": "isNotMoving", + "state": "idleSettle" + }, + { + "var": "isMovingForward", + "state": "WALKFWD" + }, + { + "var": "isMovingBackward", + "state": "WALKBWD" + }, + { + "var": "isMovingLeftHmd", + "state": "strafeLeftHmd" + }, + { + "var": "isMovingRight", + "state": "STRAFERIGHT" + }, + { + "var": "isMovingLeft", + "state": "STRAFELEFT" + }, + { + "var": "isTurningRight", + "state": "turnRight" + }, + { + "var": "isTurningLeft", + "state": "turnLeft" + }, + { + "var": "isFlying", + "state": "fly" + }, + { + "var": "isTakeoffStand", + "state": "takeoffStand" + }, + { + "var": "isTakeoffRun", + "state": "TAKEOFFRUN" + }, + { + "var": "isInAirStand", + "state": "inAirStand" + }, + { + "var": "isInAirRun", + "state": "INAIRRUN" + } + ] + }, + { + "id": "strafeLeftHmd", + "interpTarget": 5, + "interpDuration": 8, + "interpType": "snapshotPrev", + "transitions": [ + { + "var": "isNotMoving", + "state": "idleSettle" + }, + { + "var": "isMovingForward", + "state": "WALKFWD" + }, + { + "var": "isMovingBackward", + "state": "WALKBWD" + }, + { + "var": "isMovingRightHmd", + "state": "strafeRightHmd" + }, + { + "var": "isMovingRight", + "state": "STRAFERIGHT" + }, + { + "var": "isMovingLeft", + "state": "STRAFELEFT" + }, + { + "var": "isTurningRight", + "state": "turnRight" + }, + { + "var": "isTurningLeft", + "state": "turnLeft" + }, + { + "var": "isFlying", + "state": "fly" + }, + { + "var": "isTakeoffStand", + "state": "takeoffStand" + }, + { + "var": "isTakeoffRun", + "state": "TAKEOFFRUN" + }, + { + "var": "isInAirStand", + "state": "inAirStand" + }, + { + "var": "isInAirRun", + "state": "INAIRRUN" + } + ] + }, + { + "id": "fly", + "interpTarget": 6, + "interpDuration": 6, + "transitions": [ + { + "var": "isNotFlying", + "state": "idleSettle" + } + ] + }, + { + "id": "takeoffStand", + "interpTarget": 2, + "interpDuration": 2, + "transitions": [ + { + "var": "isNotTakeoff", + "state": "inAirStand" + } + ] + }, + { + "id": "TAKEOFFRUN", + "interpTarget": 2, + "interpDuration": 2, + "transitions": [ + { + "var": "isNotTakeoff", + "state": "INAIRRUN" + } + ] + }, + { + "id": "inAirStand", + "interpTarget": 3, + "interpDuration": 3, + "interpType": "snapshotPrev", + "transitions": [ + { + "var": "isNotInAir", + "state": "landStandImpact" + } + ] + }, + { + "id": "INAIRRUN", + "interpTarget": 3, + "interpDuration": 3, + "interpType": "snapshotPrev", + "transitions": [ + { + "var": "isNotInAir", + "state": "WALKFWD" + } + ] + }, + { + "id": "landStandImpact", + "interpTarget": 1, + "interpDuration": 1, + "transitions": [ + { + "var": "isFlying", + "state": "fly" + }, + { + "var": "isTakeoffStand", + "state": "takeoffStand" + }, + { + "var": "isTakeoffRun", + "state": "TAKEOFFRUN" + }, + { + "var": "landStandImpactOnDone", + "state": "landStand" + } + ] + }, + { + "id": "landStand", + "interpTarget": 1, + "interpDuration": 1, + "transitions": [ + { + "var": "isMovingForward", + "state": "WALKFWD" + }, + { + "var": "isMovingBackward", + "state": "WALKBWD" + }, + { + "var": "isMovingRight", + "state": "STRAFERIGHT" + }, + { + "var": "isMovingLeft", + "state": "STRAFELEFT" + }, + { + "var": "isTurningRight", + "state": "turnRight" + }, + { + "var": "isTurningLeft", + "state": "turnLeft" + }, + { + "var": "isFlying", + "state": "fly" + }, + { + "var": "isTakeoffStand", + "state": "takeoffStand" + }, + { + "var": "isTakeoffRun", + "state": "TAKEOFFRUN" + }, + { + "var": "isInAirStand", + "state": "inAirStand" + }, + { + "var": "isInAirRun", + "state": "INAIRRUN" + }, + { + "var": "landStandOnDone", + "state": "idle" + }, + { + "var": "isMovingRightHmd", + "state": "strafeRightHmd" + }, + { + "var": "isMovingLeftHmd", + "state": "strafeLeftHmd" + } + ] + }, + { + "id": "LANDRUN", + "interpTarget": 2, + "interpDuration": 2, + "transitions": [ + { + "var": "isFlying", + "state": "fly" + }, + { + "var": "isTakeoffStand", + "state": "takeoffStand" + }, + { + "var": "isTakeoffRun", + "state": "TAKEOFFRUN" + }, + { + "var": "landRunOnDone", + "state": "WALKFWD" + } + ] + } + ] + }, + "children": [ + { + "id": "idle", + "type": "stateMachine", + "data": { + "currentState": "idleStand", + "states": [ + { + "id": "idleStand", + "interpTarget": 6, + "interpDuration": 10, + "transitions": [ + { + "var": "isTalking", + "state": "idleTalk" + } + ] + }, + { + "id": "idleTalk", + "interpTarget": 6, + "interpDuration": 10, + "transitions": [ + { + "var": "notIsTalking", + "state": "idleStand" + } + ] + } + ] + }, + "children": [ + { + "id": "idleStand", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/idle.fbx", + "startFrame": 0.0, + "endFrame": 300.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "idleTalk", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/talk.fbx", + "startFrame": 0.0, + "endFrame": 800.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + } + ] + }, + { + "id": "WALKFWD", + "type": "blendLinearMove", + "data": { + "alpha": 0.0, + "desiredSpeed": 1.4, + "characteristicSpeeds": [ 0.5, 1.8, 2.3, 3.2, 4.5 ], + "alphaVar": "moveForwardAlpha", + "desiredSpeedVar": "moveForwardSpeed" + }, + "children": [ + { + "id": "walkFwdShort_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/walk_short_fwd.fbx", + "startFrame": 0.0, + "endFrame": 39.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "walkFwdNormal_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/walk_fwd.fbx", + "startFrame": 0.0, + "endFrame": 30.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "walkFwdFast_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/walk_fwd_fast.fbx", + "startFrame": 0.0, + "endFrame": 25.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "walkFwdJog_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jog_fwd.fbx", + "startFrame": 0.0, + "endFrame": 25.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "walkFwdRun_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/run_fwd.fbx", + "startFrame": 0.0, + "endFrame": 21.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + } + ] + }, + { + "id": "idleToWalkFwd", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/idle_to_walk.fbx", + "startFrame": 1.0, + "endFrame": 13.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] + }, + { + "id": "idleSettle", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/settle_to_idle.fbx", + "startFrame": 1.0, + "endFrame": 59.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] + }, + { + "id": "WALKBWD", + "type": "blendLinearMove", + "data": { + "alpha": 0.0, + "desiredSpeed": 1.4, + "characteristicSpeeds": [ 0.6, 1.6, 2.3, 3.1 ], + "alphaVar": "moveBackwardAlpha", + "desiredSpeedVar": "moveBackwardSpeed" + }, + "children": [ + { + "id": "walkBwdShort_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/walk_short_bwd.fbx", + "startFrame": 0.0, + "endFrame": 38.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "walkBwdFast_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/walk_bwd_fast.fbx", + "startFrame": 0.0, + "endFrame": 27.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "jogBwd_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jog_bwd.fbx", + "startFrame": 0.0, + "endFrame": 24.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "runBwd_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/run_bwd.fbx", + "startFrame": 0.0, + "endFrame": 16.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + } + ] + }, + { + "id": "turnLeft", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/turn_left.fbx", + "startFrame": 0.0, + "endFrame": 32.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "turnRight", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/turn_left.fbx", + "startFrame": 0.0, + "endFrame": 32.0, + "timeScale": 1.0, + "loopFlag": true, + "mirrorFlag": true + }, + "children": [] + }, + { + "id": "STRAFELEFT", + "type": "blendLinearMove", + "data": { + "alpha": 0.0, + "desiredSpeed": 1.4, + "characteristicSpeeds": [ 0.1, 0.5, 1.0, 2.6, 3.0 ], + "alphaVar": "moveLateralAlpha", + "desiredSpeedVar": "moveLateralSpeed" + }, + "children": [ + { + "id": "strafeLeftShortStep_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/side_step_short_left.fbx", + "startFrame": 0.0, + "endFrame": 29.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "strafeLeftStep_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/side_step_left.fbx", + "startFrame": 0.0, + "endFrame": 20.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "strafeLeftWalk_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/walk_left.fbx", + "startFrame": 0.0, + "endFrame": 35.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "strafeLeftWalkFast_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/walk_left_fast.fbx", + "startFrame": 0.0, + "endFrame": 21.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "strafeLeftJog_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jog_left.fbx", + "startFrame": 0.0, + "endFrame": 24.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + } + ] + }, + { + "id": "STRAFERIGHT", + "type": "blendLinearMove", + "data": { + "alpha": 0.0, + "desiredSpeed": 1.4, + "characteristicSpeeds": [ 0.1, 0.5, 1.0, 2.6, 3.0 ], + "alphaVar": "moveLateralAlpha", + "desiredSpeedVar": "moveLateralSpeed" + }, + "children": [ + { + "id": "strafeRightShortStep_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/side_step_short_left.fbx", + "startFrame": 0.0, + "endFrame": 29.0, + "timeScale": 1.0, + "loopFlag": true, + "mirrorFlag": true + }, + "children": [] + }, + { + "id": "strafeRightStep_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/side_step_left.fbx", + "startFrame": 0.0, + "endFrame": 20.0, + "timeScale": 1.0, + "loopFlag": true, + "mirrorFlag": true + }, + "children": [] + }, + { + "id": "strafeRightWalk_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/walk_left.fbx", + "startFrame": 0.0, + "endFrame": 35.0, + "timeScale": 1.0, + "loopFlag": true, + "mirrorFlag": true + }, + "children": [] + }, + { + "id": "strafeRightFast_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/walk_left_fast.fbx", + "startFrame": 0.0, + "endFrame": 21.0, + "timeScale": 1.0, + "loopFlag": true, + "mirrorFlag": true + }, + "children": [] + }, + { + "id": "strafeRightJog_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jog_left.fbx", + "startFrame": 0.0, + "endFrame": 24.0, + "timeScale": 1.0, + "loopFlag": true, + "mirrorFlag": true + }, + "children": [] + } + ] + }, + { + "id": "strafeLeftHmd", + "type": "blendLinearMove", + "data": { + "alpha": 0.0, + "desiredSpeed": 1.4, + "characteristicSpeeds": [ 0, 0.5, 2.5 ], + "alphaVar": "moveLateralAlpha", + "desiredSpeedVar": "moveLateralSpeed" + }, + "children": [ + { + "id": "stepLeftShort_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/side_step_short_left.fbx", + "startFrame": 0.0, + "endFrame": 29.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "stepLeft_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/side_step_left.fbx", + "startFrame": 0.0, + "endFrame": 20.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "strafeLeftAnim_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/side_step_left_fast.fbx", + "startFrame": 0.0, + "endFrame": 16.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + } + ] + }, + { + "id": "strafeRightHmd", + "type": "blendLinearMove", + "data": { + "alpha": 0.0, + "desiredSpeed": 1.4, + "characteristicSpeeds": [ 0, 0.5, 2.5 ], + "alphaVar": "moveLateralAlpha", + "desiredSpeedVar": "moveLateralSpeed" + }, + "children": [ + { + "id": "stepRightShort_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/side_step_short_left.fbx", + "startFrame": 0.0, + "endFrame": 29.0, + "timeScale": 1.0, + "loopFlag": true, + "mirrorFlag": true + }, + "children": [] + }, + { + "id": "stepRight_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/side_step_left.fbx", + "startFrame": 0.0, + "endFrame": 20.0, + "timeScale": 1.0, + "loopFlag": true, + "mirrorFlag": true + }, + "children": [] + }, + { + "id": "strafeRightAnim_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/side_step_left_fast.fbx", + "startFrame": 0.0, + "endFrame": 16.0, + "timeScale": 1.0, + "loopFlag": true, + "mirrorFlag": true + }, + "children": [] + } + ] + }, + { + "id": "fly", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/fly.fbx", + "startFrame": 1.0, + "endFrame": 80.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "takeoffStand", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jump_standing_launch.fbx", + "startFrame": 2.0, + "endFrame": 16.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] + }, + { + "id": "TAKEOFFRUN", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jump_running_launch_land.fbx", + "startFrame": 4.0, + "endFrame": 15.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] + }, + { + "id": "inAirStand", + "type": "blendLinear", + "data": { + "alpha": 0.0, + "alphaVar": "inAirAlpha" + }, + "children": [ + { + "id": "inAirStandPreApex", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jump_standing_apex.fbx", + "startFrame": 0.0, + "endFrame": 0.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] + }, + { + "id": "inAirStandApex", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jump_standing_apex.fbx", + "startFrame": 1.0, + "endFrame": 1.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] + }, + { + "id": "inAirStandPostApex", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jump_standing_apex.fbx", + "startFrame": 2.0, + "endFrame": 2.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] + } + ] + }, + { + "id": "INAIRRUN", + "type": "blendLinear", + "data": { + "alpha": 0.0, + "alphaVar": "inAirAlpha" + }, + "children": [ + { + "id": "inAirRunPreApex", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jump_running_launch_land.fbx", + "startFrame": 16.0, + "endFrame": 16.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] + }, + { + "id": "inAirRunApex", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jump_running_launch_land.fbx", + "startFrame": 22.0, + "endFrame": 22.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] + }, + { + "id": "inAirRunPostApex", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jump_running_launch_land.fbx", + "startFrame": 33.0, + "endFrame": 33.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] + } + ] + }, + { + "id": "landStandImpact", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jump_standing_land_settle.fbx", + "startFrame": 1.0, + "endFrame": 6.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] + }, + { + "id": "landStand", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jump_standing_land_settle.fbx", + "startFrame": 6.0, + "endFrame": 68.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] + }, + { + "id": "LANDRUN", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jump_running_launch_land.fbx", + "startFrame": 29.0, + "endFrame": 40.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + }, + { + "id": "userAnimA", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/idle.fbx", + "startFrame": 0.0, + "endFrame": 90.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "userAnimB", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/idle.fbx", + "startFrame": 0.0, + "endFrame": 90.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + } + ] + } +} diff --git a/libraries/animation/src/AnimSplineIK.cpp b/libraries/animation/src/AnimSplineIK.cpp index d55484f7c7..fe54aa5fe7 100644 --- a/libraries/animation/src/AnimSplineIK.cpp +++ b/libraries/animation/src/AnimSplineIK.cpp @@ -52,11 +52,11 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const // check to see if we actually need absolute poses. AnimPoseVec absolutePoses; absolutePoses.resize(_poses.size()); - //computeAbsolutePoses(absolutePoses); + computeAbsolutePoses(absolutePoses); AnimPoseVec absolutePoses2; absolutePoses2.resize(_poses.size()); // do this later - computeAbsolutePoses(absolutePoses2); + //computeAbsolutePoses(absolutePoses2); int jointIndex2 = _skeleton->nameToJointIndex("Spine2"); AnimPose origSpine2PoseAbs = _skeleton->getAbsolutePose(jointIndex2, _poses); @@ -68,44 +68,7 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const qCDebug(animation) << "original relative spine2 " << origSpine2PoseAbs; } - IKTarget target2; - //int jointIndex2 = _skeleton->nameToJointIndex("Spine2"); - if (jointIndex2 != -1) { - target2.setType(animVars.lookup("spine2Type", (int)IKTarget::Type::RotationAndPosition)); - target2.setIndex(jointIndex2); - AnimPose absPose2 = _skeleton->getAbsolutePose(jointIndex2, _poses); - glm::quat rotation2 = animVars.lookupRigToGeometry("spine2Rotation", absPose2.rot()); - glm::vec3 translation2 = animVars.lookupRigToGeometry("spine2Position", absPose2.trans()); - float weight2 = animVars.lookup("spine2Weight", "2.0"); - qCDebug(animation) << "rig to geometry" << rotation2; - - target2.setPose(rotation2, translation2); - //target2.setPose(targetSpine2.rot(), targetSpine2.trans()); - target2.setWeight(weight2); - const float* flexCoefficients2 = new float[3]{ 1.0f, 0.5f, 0.25f }; - target2.setFlexCoefficients(3, flexCoefficients2); - - - } - AnimChain jointChain2; - if (_poses.size() > 0) { - - // _snapshotChain.buildFromRelativePoses(_skeleton, _poses, target.getIndex()); - // jointChain.buildFromRelativePoses(_skeleton, _poses, target.getIndex()); - // jointChain2.buildFromRelativePoses(_skeleton, underPoses, target2.getIndex()); - jointChain2.buildFromRelativePoses(_skeleton, _poses, target2.getIndex()); - - // for each target solve target with spline - solveTargetWithSpline(context, target2, absolutePoses2, false, jointChain2); - - //jointChain.outputRelativePoses(_poses); - jointChain2.outputRelativePoses(_poses); - computeAbsolutePoses(absolutePoses); - //qCDebug(animation) << "Spine2 spline"; - //jointChain2.dump(); - //qCDebug(animation) << "Spine2Pose trans after spine2 spline: " << _skeleton->getAbsolutePose(jointIndex2, _poses).trans(); - - } + IKTarget target; int jointIndex = _skeleton->nameToJointIndex("Head"); @@ -158,9 +121,9 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const AnimPose latestSpine2Relative(originalSpine2Relative.rot(), afterSolveSpine2Rel.trans()); //jointChain.setRelativePoseAtJointIndex(jointIndex2, finalSpine2); jointChain.outputRelativePoses(_poses); - _poses[_headIndex] = jointChain.getRelativePoseAtJointIndex(_headIndex); - _poses[_skeleton->nameToJointIndex("Neck")] = jointChain.getRelativePoseAtJointIndex(_skeleton->nameToJointIndex("Neck")); - _poses[_spine2Index] = jointChain.getRelativePoseAtJointIndex(_spine2Index); + //_poses[_headIndex] = jointChain.getRelativePoseAtJointIndex(_headIndex); + //_poses[_skeleton->nameToJointIndex("Neck")] = jointChain.getRelativePoseAtJointIndex(_skeleton->nameToJointIndex("Neck")); + //_poses[_spine2Index] = jointChain.getRelativePoseAtJointIndex(_spine2Index); //custom output code for the head. just do the head neck and spine2 @@ -168,11 +131,50 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const //qCDebug(animation) << "after head spline"; //jointChain.dump(); - //computeAbsolutePoses(absolutePoses2); + computeAbsolutePoses(absolutePoses2); //origAbsAfterHeadSpline = _skeleton->getAbsolutePose(jointIndex2, _poses); // qCDebug(animation) << "Spine2 trans after head spline: " << origAbsAfterHeadSpline.trans(); } + + IKTarget target2; + //int jointIndex2 = _skeleton->nameToJointIndex("Spine2"); + if (jointIndex2 != -1) { + target2.setType(animVars.lookup("spine2Type", (int)IKTarget::Type::RotationAndPosition)); + target2.setIndex(jointIndex2); + AnimPose absPose2 = _skeleton->getAbsolutePose(jointIndex2, _poses); + glm::quat rotation2 = animVars.lookupRigToGeometry("spine2Rotation", absPose2.rot()); + glm::vec3 translation2 = animVars.lookupRigToGeometry("spine2Position", absPose2.trans()); + float weight2 = animVars.lookup("spine2Weight", "2.0"); + qCDebug(animation) << "rig to geometry" << rotation2; + + //target2.setPose(rotation2, translation2); + target2.setPose(targetSpine2.rot(), targetSpine2.trans()); + target2.setWeight(weight2); + const float* flexCoefficients2 = new float[3]{ 1.0f, 0.5f, 0.25f }; + target2.setFlexCoefficients(3, flexCoefficients2); + + + } + AnimChain jointChain2; + if (_poses.size() > 0) { + + // _snapshotChain.buildFromRelativePoses(_skeleton, _poses, target.getIndex()); + // jointChain.buildFromRelativePoses(_skeleton, _poses, target.getIndex()); + // jointChain2.buildFromRelativePoses(_skeleton, underPoses, target2.getIndex()); + jointChain2.buildFromRelativePoses(_skeleton, _poses, target2.getIndex()); + + // for each target solve target with spline + solveTargetWithSpline(context, target2, absolutePoses2, false, jointChain2); + + //jointChain.outputRelativePoses(_poses); + jointChain2.outputRelativePoses(_poses); + //computeAbsolutePoses(absolutePoses); + //qCDebug(animation) << "Spine2 spline"; + //jointChain2.dump(); + //qCDebug(animation) << "Spine2Pose trans after spine2 spline: " << _skeleton->getAbsolutePose(jointIndex2, _poses).trans(); + + } @@ -246,7 +248,7 @@ static CubicHermiteSplineFunctorWithArcLength computeSplineFromTipAndBase(const void AnimSplineIK::solveTargetWithSpline(const AnimContext& context, const IKTarget& target, const AnimPoseVec& absolutePoses, bool debug, AnimChain& chainInfoOut) const { const int baseIndex = _hipsIndex; - const int headBaseIndex = _spine2Index; + const int headBaseIndex = _spine2Index; // build spline from tip to base AnimPose tipPose = AnimPose(glm::vec3(1.0f), target.getRotation(), target.getTranslation()); @@ -369,6 +371,7 @@ void AnimSplineIK::computeAndCacheSplineJointInfosForIKTarget(const AnimContext& AnimPose tipPose = _skeleton->getAbsoluteDefaultPose(target.getIndex()); AnimPose basePose; if (target.getIndex() == _headIndex) { + //basePose = _skeleton->getAbsoluteDefaultPose(_hipsIndex); basePose = _skeleton->getAbsoluteDefaultPose(_spine2Index); } else { basePose = _skeleton->getAbsoluteDefaultPose(_hipsIndex); @@ -396,6 +399,7 @@ void AnimSplineIK::computeAndCacheSplineJointInfosForIKTarget(const AnimContext& int endIndex; if (target.getIndex() == _headIndex) { endIndex = _skeleton->getParentIndex(_spine2Index); + // endIndex = _skeleton->getParentIndex(_hipsIndex); } else { endIndex = _skeleton->getParentIndex(_hipsIndex); } From 6680ca53ad165e9ecdabd236ace78e66f2da73bb Mon Sep 17 00:00:00 2001 From: amantley Date: Sun, 20 Jan 2019 08:56:39 -0800 Subject: [PATCH 010/112] added updateHands2 which deals with two bone hands animvars --- .../avatar/avatar-animation_twoboneIK.json | 2 +- libraries/animation/src/AnimTwoBoneIK.cpp | 4 +- libraries/animation/src/Rig.cpp | 115 ++++++++++++++++++ libraries/animation/src/Rig.h | 9 ++ 4 files changed, 127 insertions(+), 3 deletions(-) diff --git a/interface/resources/avatar/avatar-animation_twoboneIK.json b/interface/resources/avatar/avatar-animation_twoboneIK.json index ba84a5d527..8a18b4859a 100644 --- a/interface/resources/avatar/avatar-animation_twoboneIK.json +++ b/interface/resources/avatar/avatar-animation_twoboneIK.json @@ -134,7 +134,7 @@ "baseJointName": "RightArm", "midJointName": "RightForeArm", "tipJointName": "RightHand", - "midHingeAxis": [ 1, 0, 0 ], + "midHingeAxis": [ 0, 0, -1 ], "alphaVar": "rightArmIKAlpha", "enabledVar": "rightArmIKEnabled", "endEffectorRotationVarVar": "rightArmIKRotationVar", diff --git a/libraries/animation/src/AnimTwoBoneIK.cpp b/libraries/animation/src/AnimTwoBoneIK.cpp index 6334f6c4fd..5df98df969 100644 --- a/libraries/animation/src/AnimTwoBoneIK.cpp +++ b/libraries/animation/src/AnimTwoBoneIK.cpp @@ -90,8 +90,8 @@ const AnimPoseVec& AnimTwoBoneIK::evaluate(const AnimVariantMap& animVars, const } _enabled = enabled; - // don't build chains or do IK if we are disbled & not interping. - if (_interpType == InterpType::None && !enabled) { + // don't build chains or do IK if we are disabled & not interping. + if (_interpType == InterpType::None){// && !enabled) { _poses = underPoses; return _poses; } diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index 44fdd8797f..e1db2fef8f 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -75,6 +75,20 @@ static const QString RIGHT_FOOT_IK_ROTATION_VAR("rightFootIKRotationVar"); static const QString MAIN_STATE_MACHINE_RIGHT_FOOT_ROTATION("mainStateMachineRightFootRotation"); static const QString MAIN_STATE_MACHINE_RIGHT_FOOT_POSITION("mainStateMachineRightFootPosition"); +static const QString LEFT_HAND_POSITION("leftHandPosition"); +static const QString LEFT_HAND_ROTATION("leftHandRotation"); +static const QString LEFT_HAND_IK_POSITION_VAR("leftHandIKPositionVar"); +static const QString LEFT_HAND_IK_ROTATION_VAR("leftHandIKRotationVar"); +static const QString MAIN_STATE_MACHINE_LEFT_HAND_POSITION("mainStateMachineLeftHandPosition"); +static const QString MAIN_STATE_MACHINE_LEFT_HAND_ROTATION("mainStateMachineLeftHandRotation"); + +static const QString RIGHT_HAND_POSITION("rightHandPosition"); +static const QString RIGHT_HAND_ROTATION("rightHandRotation"); +static const QString RIGHT_HAND_IK_POSITION_VAR("rightHandIKPositionVar"); +static const QString RIGHT_HAND_IK_ROTATION_VAR("rightHandIKRotationVar"); +static const QString MAIN_STATE_MACHINE_RIGHT_HAND_ROTATION("mainStateMachineRightHandRotation"); +static const QString MAIN_STATE_MACHINE_RIGHT_HAND_POSITION("mainStateMachineRightHandPosition"); + Rig::Rig() { // Ensure thread-safe access to the rigRegistry. @@ -1498,6 +1512,103 @@ void Rig::updateHands(bool leftHandEnabled, bool rightHandEnabled, bool hipsEnab } } +void Rig::updateHands2(bool leftHandEnabled, bool rightHandEnabled, bool headEnabled, + const AnimPose& leftHandPose, const AnimPose& rightHandPose, + const glm::mat4& rigToSensorMatrix, const glm::mat4& sensorToRigMatrix) { + + int hipsIndex = indexOfJoint("Hips"); + const float ELBOW_POLE_VECTOR_BLEND_FACTOR = 0.85f; + + if (headEnabled) { + // always do IK if head is enabled + _animVars.set("leftHandIKEnabled", true); + _animVars.set("rightHandIKEnabled", true); + } else { + // only do IK if we have a valid foot. + _animVars.set("leftHandIKEnabled", leftHandEnabled); + _animVars.set("rightHandIKEnabled", rightHandEnabled); + } + + if (leftHandEnabled) { + + _animVars.set(LEFT_HAND_POSITION, leftHandPose.trans()); + _animVars.set(LEFT_HAND_ROTATION, leftHandPose.rot()); + + // We want to drive the IK directly from the trackers. + _animVars.set(LEFT_HAND_IK_POSITION_VAR, LEFT_HAND_POSITION); + _animVars.set(LEFT_HAND_IK_ROTATION_VAR, LEFT_HAND_ROTATION); + + int handJointIndex = _animSkeleton->nameToJointIndex("LeftHand"); + int elbowJointIndex = _animSkeleton->nameToJointIndex("LeftForeArm"); + int shoulderJointIndex = _animSkeleton->nameToJointIndex("LeftArm"); + int oppositeArmJointIndex = _animSkeleton->nameToJointIndex("LeftArm"); + glm::vec3 poleVector; + bool usePoleVector = calculateElbowPoleVector(handJointIndex, elbowJointIndex, shoulderJointIndex, oppositeArmJointIndex, poleVector); + glm::vec3 sensorPoleVector = transformVectorFast(rigToSensorMatrix, poleVector); + + // smooth toward desired pole vector from previous pole vector... to reduce jitter, but in sensor space. + if (!_prevLeftHandPoleVectorValid) { + _prevLeftHandPoleVectorValid = true; + _prevLeftHandPoleVector = sensorPoleVector; + } + glm::quat deltaRot = rotationBetween(_prevLeftHandPoleVector, sensorPoleVector); + glm::quat smoothDeltaRot = safeMix(deltaRot, Quaternions::IDENTITY, ELBOW_POLE_VECTOR_BLEND_FACTOR); + _prevLeftHandPoleVector = smoothDeltaRot * _prevLeftHandPoleVector; + + _animVars.set("leftHandPoleVectorEnabled", true); + _animVars.set("leftHandPoleVector", transformVectorFast(sensorToRigMatrix, _prevLeftFootPoleVector)); + } else { + // We want to drive the IK from the underlying animation. + // This gives us the ability to squat while in the HMD, without the feet from dipping under the floor. + _animVars.set(LEFT_HAND_IK_POSITION_VAR, MAIN_STATE_MACHINE_LEFT_HAND_POSITION); + _animVars.set(LEFT_HAND_IK_ROTATION_VAR, MAIN_STATE_MACHINE_LEFT_HAND_ROTATION); + + // We want to match the animated knee pose as close as possible, so don't use poleVectors + _animVars.set("leftHandPoleVectorEnabled", false); + _prevLeftHandPoleVectorValid = false; + } + + if (rightHandEnabled) { + + _animVars.set(RIGHT_HAND_POSITION, rightHandPose.trans()); + _animVars.set(RIGHT_HAND_ROTATION, rightHandPose.rot()); + + // We want to drive the IK directly from the trackers. + _animVars.set(RIGHT_HAND_IK_POSITION_VAR, RIGHT_HAND_POSITION); + _animVars.set(RIGHT_HAND_IK_ROTATION_VAR, RIGHT_HAND_ROTATION); + + int handJointIndex = _animSkeleton->nameToJointIndex("RightHand"); + int elbowJointIndex = _animSkeleton->nameToJointIndex("RightForeArm"); + int shoulderJointIndex = _animSkeleton->nameToJointIndex("RightArm"); + int oppositeArmJointIndex = _animSkeleton->nameToJointIndex("RightArm"); + glm::vec3 poleVector; + bool usePoleVector = calculateElbowPoleVector(handJointIndex, elbowJointIndex, shoulderJointIndex, oppositeArmJointIndex, poleVector); + glm::vec3 sensorPoleVector = transformVectorFast(rigToSensorMatrix, poleVector); + + // smooth toward desired pole vector from previous pole vector... to reduce jitter, but in sensor space. + if (!_prevRightHandPoleVectorValid) { + _prevRightHandPoleVectorValid = true; + _prevRightHandPoleVector = sensorPoleVector; + } + glm::quat deltaRot = rotationBetween(_prevRightHandPoleVector, sensorPoleVector); + glm::quat smoothDeltaRot = safeMix(deltaRot, Quaternions::IDENTITY, ELBOW_POLE_VECTOR_BLEND_FACTOR); + _prevRightHandPoleVector = smoothDeltaRot * _prevRightHandPoleVector; + + _animVars.set("rightHandPoleVectorEnabled", true); + _animVars.set("rightHandPoleVector", transformVectorFast(sensorToRigMatrix, _prevRightFootPoleVector)); + } else { + // We want to drive the IK from the underlying animation. + // This gives us the ability to squat while in the HMD, without the feet from dipping under the floor. + _animVars.set(RIGHT_HAND_IK_POSITION_VAR, MAIN_STATE_MACHINE_RIGHT_HAND_POSITION); + _animVars.set(RIGHT_HAND_IK_ROTATION_VAR, MAIN_STATE_MACHINE_RIGHT_HAND_ROTATION); + + // We want to match the animated knee pose as close as possible, so don't use poleVectors + _animVars.set("rightHandPoleVectorEnabled", false); + _prevRightHandPoleVectorValid = false; + } + +} + void Rig::updateFeet(bool leftFootEnabled, bool rightFootEnabled, bool headEnabled, const AnimPose& leftFootPose, const AnimPose& rightFootPose, const glm::mat4& rigToSensorMatrix, const glm::mat4& sensorToRigMatrix) { @@ -1750,6 +1861,10 @@ void Rig::updateFromControllerParameters(const ControllerParameters& params, flo params.hipsShapeInfo, params.spineShapeInfo, params.spine1ShapeInfo, params.spine2ShapeInfo, params.rigToSensorMatrix, sensorToRigMatrix); + updateHands2(leftHandEnabled, rightHandEnabled, _headEnabled, + params.primaryControllerPoses[PrimaryControllerType_LeftHand], params.primaryControllerPoses[PrimaryControllerType_RightHand], + params.rigToSensorMatrix, sensorToRigMatrix); + updateFeet(leftFootEnabled, rightFootEnabled, _headEnabled, params.primaryControllerPoses[PrimaryControllerType_LeftFoot], params.primaryControllerPoses[PrimaryControllerType_RightFoot], params.rigToSensorMatrix, sensorToRigMatrix); diff --git a/libraries/animation/src/Rig.h b/libraries/animation/src/Rig.h index 41c25a3c3e..e6effe9e53 100644 --- a/libraries/animation/src/Rig.h +++ b/libraries/animation/src/Rig.h @@ -250,6 +250,9 @@ protected: const HFMJointShapeInfo& hipsShapeInfo, const HFMJointShapeInfo& spineShapeInfo, const HFMJointShapeInfo& spine1ShapeInfo, const HFMJointShapeInfo& spine2ShapeInfo, const glm::mat4& rigToSensorMatrix, const glm::mat4& sensorToRigMatrix); + void updateHands2(bool leftHandEnabled, bool rightHandEnabled, bool headEnabled, + const AnimPose& leftHandPose, const AnimPose& rightHandPose, + const glm::mat4& rigToSensorMatrix, const glm::mat4& sensorToRigMatrix); void updateFeet(bool leftFootEnabled, bool rightFootEnabled, bool headEnabled, const AnimPose& leftFootPose, const AnimPose& rightFootPose, const glm::mat4& rigToSensorMatrix, const glm::mat4& sensorToRigMatrix); @@ -414,6 +417,12 @@ protected: glm::vec3 _prevLeftFootPoleVector { Vectors::UNIT_Z }; // sensor space bool _prevLeftFootPoleVectorValid { false }; + glm::vec3 _prevRightHandPoleVector { Vectors::UNIT_Z }; // sensor space + bool _prevRightHandPoleVectorValid { false }; + + glm::vec3 _prevLeftHandPoleVector { Vectors::UNIT_Z }; // sensor space + bool _prevLeftHandPoleVectorValid { false }; + int _rigId; bool _headEnabled { false }; bool _computeNetworkAnimation { false }; From 8d88c627b01161ed50942e192981c063f1dbb9df Mon Sep 17 00:00:00 2001 From: amantley Date: Mon, 21 Jan 2019 17:41:08 -0800 Subject: [PATCH 011/112] nearly have the arms legs and back working with out the ik node --- .../avatar/avatar-animation_twoboneIK.json | 3479 ++++++++--------- interface/src/Application.cpp | 1 - .../animation/src/AnimInverseKinematics.cpp | 13 +- libraries/animation/src/AnimSplineIK.cpp | 24 +- libraries/animation/src/AnimTwoBoneIK.cpp | 4 +- libraries/animation/src/Rig.cpp | 14 +- 6 files changed, 1773 insertions(+), 1762 deletions(-) diff --git a/interface/resources/avatar/avatar-animation_twoboneIK.json b/interface/resources/avatar/avatar-animation_twoboneIK.json index 8a18b4859a..45cb7b570e 100644 --- a/interface/resources/avatar/avatar-animation_twoboneIK.json +++ b/interface/resources/avatar/avatar-animation_twoboneIK.json @@ -112,7 +112,7 @@ }, "children": [ { - "id": "rightArmPoleVector", + "id": "rightHandPoleVector", "type": "poleVectorConstraint", "data": { "enabled": false, @@ -125,7 +125,7 @@ }, "children": [ { - "id": "rightArmIK", + "id": "rightHandIK", "type": "twoBoneIK", "data": { "alpha": 1.0, @@ -135,390 +135,147 @@ "midJointName": "RightForeArm", "tipJointName": "RightHand", "midHingeAxis": [ 0, 0, -1 ], - "alphaVar": "rightArmIKAlpha", - "enabledVar": "rightArmIKEnabled", - "endEffectorRotationVarVar": "rightArmIKRotationVar", - "endEffectorPositionVarVar": "rightArmIKPositionVar" + "alphaVar": "rightHandIKAlpha", + "enabledVar": "rightHandIKEnabled", + "endEffectorRotationVarVar": "rightHandIKRotationVar", + "endEffectorPositionVarVar": "rightHandIKPositionVar" }, "children": [ { - "id": "ikOverlay", - "type": "overlay", + "id": "leftHandPoleVector", + "type": "poleVectorConstraint", "data": { - "alpha": 1.0, - "alphaVar": "ikOverlayAlpha", - "boneSet": "fullBody" + "enabled": false, + "referenceVector": [ 0, 0, 1 ], + "baseJointName": "LeftArm", + "midJointName": "LeftForeArm", + "tipJointName": "LeftHand", + "enabledVar": "leftHandPoleVectorEnabled", + "poleVectorVar": "leftHandPoleVector" }, "children": [ { - "id": "ik", - "type": "inverseKinematics", + "id": "leftHandIK", + "type": "twoBoneIK", "data": { - "solutionSource": "relaxToUnderPoses", - "solutionSourceVar": "solutionSource", - "targets": [ - { - "jointName": "Hips", - "positionVar": "hipsPosition", - "rotationVar": "hipsRotation", - "typeVar": "hipsType", - "weightVar": "hipsWeight", - "weight": 1.0, - "flexCoefficients": [ 1 ] - }, - { - "jointName": "LeftHand", - "positionVar": "leftHandPosition", - "rotationVar": "leftHandRotation", - "typeVar": "leftHandType", - "weightVar": "leftHandWeight", - "weight": 1.0, - "flexCoefficients": [ 1, 0.5, 0.5, 0.2, 0.01, 0.005, 0.001, 0.0, 0.0 ], - "poleVectorEnabledVar": "leftHandPoleVectorEnabled", - "poleReferenceVectorVar": "leftHandPoleReferenceVector", - "poleVectorVar": "leftHandPoleVector" - } - ] - }, - "children": [] - }, - { - "id": "defaultPoseOverlay", - "type": "overlay", - "data": { - "alpha": 0.0, - "alphaVar": "defaultPoseOverlayAlpha", - "boneSet": "fullBody", - "boneSetVar": "defaultPoseOverlayBoneSet" + "alpha": 1.0, + "enabled": false, + "interpDuration": 15, + "baseJointName": "LeftArm", + "midJointName": "LeftForeArm", + "tipJointName": "LeftHand", + "midHingeAxis": [ 0, 0, 1 ], + "alphaVar": "leftHandIKAlpha", + "enabledVar": "leftHandIKEnabled", + "endEffectorRotationVarVar": "leftHandIKRotationVar", + "endEffectorPositionVarVar": "leftHandIKPositionVar" }, "children": [ { - "id": "defaultPose", - "type": "defaultPose", - "data": { - }, - "children": [] - }, - { - "id": "rightHandOverlay", + "id": "defaultPoseOverlay", "type": "overlay", "data": { "alpha": 0.0, - "boneSet": "rightHand", - "alphaVar": "rightHandOverlayAlpha" + "alphaVar": "defaultPoseOverlayAlpha", + "boneSet": "fullBody", + "boneSetVar": "defaultPoseOverlayBoneSet" }, "children": [ { - "id": "rightHandStateMachine", - "type": "stateMachine", + "id": "defaultPose", + "type": "defaultPose", "data": { - "currentState": "rightHandGrasp", - "states": [ - { - "id": "rightHandGrasp", - "interpTarget": 3, - "interpDuration": 3, - "transitions": [ - { - "var": "isRightIndexPoint", - "state": "rightIndexPoint" - }, - { - "var": "isRightThumbRaise", - "state": "rightThumbRaise" - }, - { - "var": "isRightIndexPointAndThumbRaise", - "state": "rightIndexPointAndThumbRaise" - } - ] - }, - { - "id": "rightIndexPoint", - "interpTarget": 15, - "interpDuration": 3, - "transitions": [ - { - "var": "isRightHandGrasp", - "state": "rightHandGrasp" - }, - { - "var": "isRightThumbRaise", - "state": "rightThumbRaise" - }, - { - "var": "isRightIndexPointAndThumbRaise", - "state": "rightIndexPointAndThumbRaise" - } - ] - }, - { - "id": "rightThumbRaise", - "interpTarget": 15, - "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" - } - ] - } - ] }, - "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": [] - } - ] - } - ] + "children": [] }, { - "id": "leftHandOverlay", + "id": "rightHandOverlay", "type": "overlay", "data": { "alpha": 0.0, - "boneSet": "leftHand", - "alphaVar": "leftHandOverlayAlpha" + "boneSet": "rightHand", + "alphaVar": "rightHandOverlayAlpha" }, "children": [ { - "id": "leftHandStateMachine", + "id": "rightHandStateMachine", "type": "stateMachine", "data": { - "currentState": "leftHandGrasp", + "currentState": "rightHandGrasp", "states": [ { - "id": "leftHandGrasp", + "id": "rightHandGrasp", "interpTarget": 3, "interpDuration": 3, "transitions": [ { - "var": "isLeftIndexPoint", - "state": "leftIndexPoint" + "var": "isRightIndexPoint", + "state": "rightIndexPoint" }, { - "var": "isLeftThumbRaise", - "state": "leftThumbRaise" + "var": "isRightThumbRaise", + "state": "rightThumbRaise" }, { - "var": "isLeftIndexPointAndThumbRaise", - "state": "leftIndexPointAndThumbRaise" + "var": "isRightIndexPointAndThumbRaise", + "state": "rightIndexPointAndThumbRaise" } ] }, { - "id": "leftIndexPoint", + "id": "rightIndexPoint", "interpTarget": 15, "interpDuration": 3, "transitions": [ { - "var": "isLeftHandGrasp", - "state": "leftHandGrasp" + "var": "isRightHandGrasp", + "state": "rightHandGrasp" }, { - "var": "isLeftThumbRaise", - "state": "leftThumbRaise" + "var": "isRightThumbRaise", + "state": "rightThumbRaise" }, { - "var": "isLeftIndexPointAndThumbRaise", - "state": "leftIndexPointAndThumbRaise" + "var": "isRightIndexPointAndThumbRaise", + "state": "rightIndexPointAndThumbRaise" } ] }, { - "id": "leftThumbRaise", + "id": "rightThumbRaise", "interpTarget": 15, "interpDuration": 3, "transitions": [ { - "var": "isLeftHandGrasp", - "state": "leftHandGrasp" + "var": "isRightHandGrasp", + "state": "rightHandGrasp" }, { - "var": "isLeftIndexPoint", - "state": "leftIndexPoint" + "var": "isRightIndexPoint", + "state": "rightIndexPoint" }, { - "var": "isLeftIndexPointAndThumbRaise", - "state": "leftIndexPointAndThumbRaise" + "var": "isRightIndexPointAndThumbRaise", + "state": "rightIndexPointAndThumbRaise" } ] }, { - "id": "leftIndexPointAndThumbRaise", + "id": "rightIndexPointAndThumbRaise", "interpTarget": 15, "interpDuration": 3, "transitions": [ { - "var": "isLeftHandGrasp", - "state": "leftHandGrasp" + "var": "isRightHandGrasp", + "state": "rightHandGrasp" }, { - "var": "isLeftIndexPoint", - "state": "leftIndexPoint" + "var": "isRightIndexPoint", + "state": "rightIndexPoint" }, { - "var": "isLeftThumbRaise", - "state": "leftThumbRaise" + "var": "isRightThumbRaise", + "state": "rightThumbRaise" } ] } @@ -526,18 +283,18 @@ }, "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, @@ -546,12 +303,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 }, @@ -560,18 +317,18 @@ ] }, { - "id": "leftIndexPoint", + "id": "rightIndexPoint", "type": "blendLinear", "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, @@ -580,10 +337,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, @@ -594,18 +351,18 @@ ] }, { - "id": "leftThumbRaise", + "id": "rightThumbRaise", "type": "blendLinear", "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, @@ -614,10 +371,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, @@ -628,18 +385,18 @@ ] }, { - "id": "leftIndexPointAndThumbRaise", + "id": "rightIndexPointAndThumbRaise", "type": "blendLinear", "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, @@ -648,10 +405,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, @@ -664,871 +421,93 @@ ] }, { - "id": "mainStateMachine", - "type": "stateMachine", + "id": "leftHandOverlay", + "type": "overlay", "data": { - "outputJoints": [ "LeftFoot", "RightFoot" ], - "currentState": "idle", - "states": [ - { - "id": "idle", - "interpTarget": 20, - "interpDuration": 8, - "interpType": "snapshotPrev", - "transitions": [ - { - "var": "isMovingForward", - "state": "WALKFWD" - }, - { - "var": "isMovingBackward", - "state": "WALKBWD" - }, - { - "var": "isMovingRight", - "state": "STRAFERIGHT" - }, - { - "var": "isMovingLeft", - "state": "STRAFELEFT" - }, - { - "var": "isTurningRight", - "state": "turnRight" - }, - { - "var": "isTurningLeft", - "state": "turnLeft" - }, - { - "var": "isFlying", - "state": "fly" - }, - { - "var": "isTakeoffStand", - "state": "takeoffStand" - }, - { - "var": "isTakeoffRun", - "state": "TAKEOFFRUN" - }, - { - "var": "isInAirStand", - "state": "inAirStand" - }, - { - "var": "isInAirRun", - "state": "INAIRRUN" - }, - { - "var": "isMovingRightHmd", - "state": "strafeRightHmd" - }, - { - "var": "isMovingLeftHmd", - "state": "strafeLeftHmd" - } - ] - }, - { - "id": "idleToWalkFwd", - "interpTarget": 12, - "interpDuration": 8, - "transitions": [ - { - "var": "idleToWalkFwdOnDone", - "state": "WALKFWD" - }, - { - "var": "isNotMoving", - "state": "idle" - }, - { - "var": "isMovingBackward", - "state": "WALKBWD" - }, - { - "var": "isMovingRight", - "state": "STRAFERIGHT" - }, - { - "var": "isMovingLeft", - "state": "STRAFELEFT" - }, - { - "var": "isTurningRight", - "state": "turnRight" - }, - { - "var": "isTurningLeft", - "state": "turnLeft" - }, - { - "var": "isFlying", - "state": "fly" - }, - { - "var": "isTakeoffStand", - "state": "takeoffStand" - }, - { - "var": "isTakeoffRun", - "state": "TAKEOFFRUN" - }, - { - "var": "isInAirStand", - "state": "inAirStand" - }, - { - "var": "isInAirRun", - "state": "INAIRRUN" - }, - { - "var": "isMovingRightHmd", - "state": "strafeRightHmd" - }, - { - "var": "isMovingLeftHmd", - "state": "strafeLeftHmd" - } - ] - }, - { - "id": "idleSettle", - "interpTarget": 15, - "interpDuration": 8, - "interpType": "snapshotPrev", - "transitions": [ - { - "var": "idleSettleOnDone", - "state": "idle" - }, - { - "var": "isMovingForward", - "state": "WALKFWD" - }, - { - "var": "isMovingBackward", - "state": "WALKBWD" - }, - { - "var": "isMovingRight", - "state": "STRAFERIGHT" - }, - { - "var": "isMovingLeft", - "state": "STRAFELEFT" - }, - { - "var": "isMovingRightHmd", - "state": "strafeRightHmd" - }, - { - "var": "isMovingLeftHmd", - "state": "strafeLeftHmd" - }, - { - "var": "isTurningRight", - "state": "turnRight" - }, - { - "var": "isTurningLeft", - "state": "turnLeft" - }, - { - "var": "isFlying", - "state": "fly" - }, - { - "var": "isTakeoffStand", - "state": "takeoffStand" - }, - { - "var": "isTakeoffRun", - "state": "TAKEOFFRUN" - }, - { - "var": "isInAirStand", - "state": "inAirStand" - }, - { - "var": "isInAirRun", - "state": "INAIRRUN" - } - ] - }, - { - "id": "WALKFWD", - "interpTarget": 35, - "interpDuration": 10, - "interpType": "snapshotPrev", - "transitions": [ - { - "var": "isNotMoving", - "state": "idleSettle" - }, - { - "var": "isMovingBackward", - "state": "WALKBWD" - }, - { - "var": "isMovingRight", - "state": "STRAFERIGHT" - }, - { - "var": "isMovingLeft", - "state": "STRAFELEFT" - }, - { - "var": "isTurningRight", - "state": "turnRight" - }, - { - "var": "isTurningLeft", - "state": "turnLeft" - }, - { - "var": "isFlying", - "state": "fly" - }, - { - "var": "isTakeoffStand", - "state": "takeoffStand" - }, - { - "var": "isTakeoffRun", - "state": "TAKEOFFRUN" - }, - { - "var": "isInAirStand", - "state": "inAirStand" - }, - { - "var": "isInAirRun", - "state": "INAIRRUN" - }, - { - "var": "isMovingRightHmd", - "state": "strafeRightHmd" - }, - { - "var": "isMovingLeftHmd", - "state": "strafeLeftHmd" - } - ] - }, - { - "id": "WALKBWD", - "interpTarget": 35, - "interpDuration": 10, - "interpType": "snapshotPrev", - "transitions": [ - { - "var": "isNotMoving", - "state": "idleSettle" - }, - { - "var": "isMovingForward", - "state": "WALKFWD" - }, - { - "var": "isMovingRight", - "state": "STRAFERIGHT" - }, - { - "var": "isMovingLeft", - "state": "STRAFELEFT" - }, - { - "var": "isTurningRight", - "state": "turnRight" - }, - { - "var": "isTurningLeft", - "state": "turnLeft" - }, - { - "var": "isFlying", - "state": "fly" - }, - { - "var": "isTakeoffStand", - "state": "takeoffStand" - }, - { - "var": "isTakeoffRun", - "state": "TAKEOFFRUN" - }, - { - "var": "isInAirStand", - "state": "inAirStand" - }, - { - "var": "isInAirRun", - "state": "INAIRRUN" - }, - { - "var": "isMovingRightHmd", - "state": "strafeRightHmd" - }, - { - "var": "isMovingLeftHmd", - "state": "strafeLeftHmd" - } - ] - }, - { - "id": "STRAFERIGHT", - "interpTarget": 25, - "interpDuration": 8, - "interpType": "snapshotPrev", - "transitions": [ - { - "var": "isNotMoving", - "state": "idleSettle" - }, - { - "var": "isMovingForward", - "state": "WALKFWD" - }, - { - "var": "isMovingBackward", - "state": "WALKBWD" - }, - { - "var": "isMovingLeft", - "state": "STRAFELEFT" - }, - { - "var": "isTurningRight", - "state": "turnRight" - }, - { - "var": "isTurningLeft", - "state": "turnLeft" - }, - { - "var": "isFlying", - "state": "fly" - }, - { - "var": "isTakeoffStand", - "state": "takeoffStand" - }, - { - "var": "isTakeoffRun", - "state": "TAKEOFFRUN" - }, - { - "var": "isInAirStand", - "state": "inAirStand" - }, - { - "var": "isInAirRun", - "state": "INAIRRUN" - }, - { - "var": "isMovingRightHmd", - "state": "strafeRightHmd" - }, - { - "var": "isMovingLeftHmd", - "state": "strafeLeftHmd" - } - ] - }, - { - "id": "STRAFELEFT", - "interpTarget": 25, - "interpDuration": 8, - "interpType": "snapshotPrev", - "transitions": [ - { - "var": "isNotMoving", - "state": "idleSettle" - }, - { - "var": "isMovingForward", - "state": "WALKFWD" - }, - { - "var": "isMovingBackward", - "state": "WALKBWD" - }, - { - "var": "isMovingRight", - "state": "STRAFERIGHT" - }, - { - "var": "isTurningRight", - "state": "turnRight" - }, - { - "var": "isTurningLeft", - "state": "turnLeft" - }, - { - "var": "isFlying", - "state": "fly" - }, - { - "var": "isTakeoffStand", - "state": "takeoffStand" - }, - { - "var": "isTakeoffRun", - "state": "TAKEOFFRUN" - }, - { - "var": "isInAirStand", - "state": "inAirStand" - }, - { - "var": "isInAirRun", - "state": "INAIRRUN" - }, - { - "var": "isMovingRightHmd", - "state": "strafeRightHmd" - }, - { - "var": "isMovingLeftHmd", - "state": "strafeLeftHmd" - } - ] - }, - { - "id": "turnRight", - "interpTarget": 6, - "interpDuration": 8, - "transitions": [ - { - "var": "isNotTurning", - "state": "idle" - }, - { - "var": "isMovingForward", - "state": "WALKFWD" - }, - { - "var": "isMovingBackward", - "state": "WALKBWD" - }, - { - "var": "isMovingRight", - "state": "STRAFERIGHT" - }, - { - "var": "isMovingLeft", - "state": "STRAFELEFT" - }, - { - "var": "isTurningLeft", - "state": "turnLeft" - }, - { - "var": "isFlying", - "state": "fly" - }, - { - "var": "isTakeoffStand", - "state": "takeoffStand" - }, - { - "var": "isTakeoffRun", - "state": "TAKEOFFRUN" - }, - { - "var": "isInAirStand", - "state": "inAirStand" - }, - { - "var": "isInAirRun", - "state": "INAIRRUN" - }, - { - "var": "isMovingRightHmd", - "state": "strafeRightHmd" - }, - { - "var": "isMovingLeftHmd", - "state": "strafeLeftHmd" - } - ] - }, - { - "id": "turnLeft", - "interpTarget": 6, - "interpDuration": 8, - "transitions": [ - { - "var": "isNotTurning", - "state": "idle" - }, - { - "var": "isMovingForward", - "state": "WALKFWD" - }, - { - "var": "isMovingBackward", - "state": "WALKBWD" - }, - { - "var": "isMovingRight", - "state": "STRAFERIGHT" - }, - { - "var": "isMovingLeft", - "state": "STRAFELEFT" - }, - { - "var": "isTurningRight", - "state": "turnRight" - }, - { - "var": "isFlying", - "state": "fly" - }, - { - "var": "isTakeoffStand", - "state": "takeoffStand" - }, - { - "var": "isTakeoffRun", - "state": "TAKEOFFRUN" - }, - { - "var": "isInAirStand", - "state": "inAirStand" - }, - { - "var": "isInAirRun", - "state": "INAIRRUN" - }, - { - "var": "isMovingRightHmd", - "state": "strafeRightHmd" - }, - { - "var": "isMovingLeftHmd", - "state": "strafeLeftHmd" - } - ] - }, - { - "id": "strafeRightHmd", - "interpTarget": 5, - "interpDuration": 8, - "interpType": "snapshotPrev", - "transitions": [ - { - "var": "isNotMoving", - "state": "idleSettle" - }, - { - "var": "isMovingForward", - "state": "WALKFWD" - }, - { - "var": "isMovingBackward", - "state": "WALKBWD" - }, - { - "var": "isMovingLeftHmd", - "state": "strafeLeftHmd" - }, - { - "var": "isMovingRight", - "state": "STRAFERIGHT" - }, - { - "var": "isMovingLeft", - "state": "STRAFELEFT" - }, - { - "var": "isTurningRight", - "state": "turnRight" - }, - { - "var": "isTurningLeft", - "state": "turnLeft" - }, - { - "var": "isFlying", - "state": "fly" - }, - { - "var": "isTakeoffStand", - "state": "takeoffStand" - }, - { - "var": "isTakeoffRun", - "state": "TAKEOFFRUN" - }, - { - "var": "isInAirStand", - "state": "inAirStand" - }, - { - "var": "isInAirRun", - "state": "INAIRRUN" - } - ] - }, - { - "id": "strafeLeftHmd", - "interpTarget": 5, - "interpDuration": 8, - "interpType": "snapshotPrev", - "transitions": [ - { - "var": "isNotMoving", - "state": "idleSettle" - }, - { - "var": "isMovingForward", - "state": "WALKFWD" - }, - { - "var": "isMovingBackward", - "state": "WALKBWD" - }, - { - "var": "isMovingRightHmd", - "state": "strafeRightHmd" - }, - { - "var": "isMovingRight", - "state": "STRAFERIGHT" - }, - { - "var": "isMovingLeft", - "state": "STRAFELEFT" - }, - { - "var": "isTurningRight", - "state": "turnRight" - }, - { - "var": "isTurningLeft", - "state": "turnLeft" - }, - { - "var": "isFlying", - "state": "fly" - }, - { - "var": "isTakeoffStand", - "state": "takeoffStand" - }, - { - "var": "isTakeoffRun", - "state": "TAKEOFFRUN" - }, - { - "var": "isInAirStand", - "state": "inAirStand" - }, - { - "var": "isInAirRun", - "state": "INAIRRUN" - } - ] - }, - { - "id": "fly", - "interpTarget": 6, - "interpDuration": 6, - "transitions": [ - { - "var": "isNotFlying", - "state": "idleSettle" - } - ] - }, - { - "id": "takeoffStand", - "interpTarget": 2, - "interpDuration": 2, - "transitions": [ - { - "var": "isNotTakeoff", - "state": "inAirStand" - } - ] - }, - { - "id": "TAKEOFFRUN", - "interpTarget": 2, - "interpDuration": 2, - "transitions": [ - { - "var": "isNotTakeoff", - "state": "INAIRRUN" - } - ] - }, - { - "id": "inAirStand", - "interpTarget": 3, - "interpDuration": 3, - "interpType": "snapshotPrev", - "transitions": [ - { - "var": "isNotInAir", - "state": "landStandImpact" - } - ] - }, - { - "id": "INAIRRUN", - "interpTarget": 3, - "interpDuration": 3, - "interpType": "snapshotPrev", - "transitions": [ - { - "var": "isNotInAir", - "state": "WALKFWD" - } - ] - }, - { - "id": "landStandImpact", - "interpTarget": 1, - "interpDuration": 1, - "transitions": [ - { - "var": "isFlying", - "state": "fly" - }, - { - "var": "isTakeoffStand", - "state": "takeoffStand" - }, - { - "var": "isTakeoffRun", - "state": "TAKEOFFRUN" - }, - { - "var": "landStandImpactOnDone", - "state": "landStand" - } - ] - }, - { - "id": "landStand", - "interpTarget": 1, - "interpDuration": 1, - "transitions": [ - { - "var": "isMovingForward", - "state": "WALKFWD" - }, - { - "var": "isMovingBackward", - "state": "WALKBWD" - }, - { - "var": "isMovingRight", - "state": "STRAFERIGHT" - }, - { - "var": "isMovingLeft", - "state": "STRAFELEFT" - }, - { - "var": "isTurningRight", - "state": "turnRight" - }, - { - "var": "isTurningLeft", - "state": "turnLeft" - }, - { - "var": "isFlying", - "state": "fly" - }, - { - "var": "isTakeoffStand", - "state": "takeoffStand" - }, - { - "var": "isTakeoffRun", - "state": "TAKEOFFRUN" - }, - { - "var": "isInAirStand", - "state": "inAirStand" - }, - { - "var": "isInAirRun", - "state": "INAIRRUN" - }, - { - "var": "landStandOnDone", - "state": "idle" - }, - { - "var": "isMovingRightHmd", - "state": "strafeRightHmd" - }, - { - "var": "isMovingLeftHmd", - "state": "strafeLeftHmd" - } - ] - }, - { - "id": "LANDRUN", - "interpTarget": 2, - "interpDuration": 2, - "transitions": [ - { - "var": "isFlying", - "state": "fly" - }, - { - "var": "isTakeoffStand", - "state": "takeoffStand" - }, - { - "var": "isTakeoffRun", - "state": "TAKEOFFRUN" - }, - { - "var": "landRunOnDone", - "state": "WALKFWD" - } - ] - } - ] + "alpha": 0.0, + "boneSet": "leftHand", + "alphaVar": "leftHandOverlayAlpha" }, "children": [ { - "id": "idle", + "id": "leftHandStateMachine", "type": "stateMachine", "data": { - "currentState": "idleStand", + "currentState": "leftHandGrasp", "states": [ { - "id": "idleStand", - "interpTarget": 6, - "interpDuration": 10, + "id": "leftHandGrasp", + "interpTarget": 3, + "interpDuration": 3, "transitions": [ { - "var": "isTalking", - "state": "idleTalk" + "var": "isLeftIndexPoint", + "state": "leftIndexPoint" + }, + { + "var": "isLeftThumbRaise", + "state": "leftThumbRaise" + }, + { + "var": "isLeftIndexPointAndThumbRaise", + "state": "leftIndexPointAndThumbRaise" } ] }, { - "id": "idleTalk", - "interpTarget": 6, - "interpDuration": 10, + "id": "leftIndexPoint", + "interpTarget": 15, + "interpDuration": 3, "transitions": [ { - "var": "notIsTalking", - "state": "idleStand" + "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" } ] } @@ -1536,562 +515,1494 @@ }, "children": [ { - "id": "idleStand", - "type": "clip", + "id": "leftHandGrasp", + "type": "blendLinear", "data": { - "url": "qrc:///avatar/animations/idle.fbx", - "startFrame": 0.0, - "endFrame": 300.0, - "timeScale": 1.0, - "loopFlag": true + "alpha": 0.0, + "alphaVar": "leftHandGraspAlpha" }, - "children": [] + "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": "idleTalk", - "type": "clip", + "id": "leftIndexPoint", + "type": "blendLinear", "data": { - "url": "qrc:///avatar/animations/talk.fbx", - "startFrame": 0.0, - "endFrame": 800.0, - "timeScale": 1.0, - "loopFlag": true + "alpha": 0.0, + "alphaVar": "leftHandGraspAlpha" }, - "children": [] + "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": "WALKFWD", - "type": "blendLinearMove", + "id": "mainStateMachine", + "type": "stateMachine", "data": { - "alpha": 0.0, - "desiredSpeed": 1.4, - "characteristicSpeeds": [ 0.5, 1.8, 2.3, 3.2, 4.5 ], - "alphaVar": "moveForwardAlpha", - "desiredSpeedVar": "moveForwardSpeed" + "outputJoints": [ "LeftFoot", "RightFoot" ], + "currentState": "idle", + "states": [ + { + "id": "idle", + "interpTarget": 20, + "interpDuration": 8, + "interpType": "snapshotPrev", + "transitions": [ + { + "var": "isMovingForward", + "state": "WALKFWD" + }, + { + "var": "isMovingBackward", + "state": "WALKBWD" + }, + { + "var": "isMovingRight", + "state": "STRAFERIGHT" + }, + { + "var": "isMovingLeft", + "state": "STRAFELEFT" + }, + { + "var": "isTurningRight", + "state": "turnRight" + }, + { + "var": "isTurningLeft", + "state": "turnLeft" + }, + { + "var": "isFlying", + "state": "fly" + }, + { + "var": "isTakeoffStand", + "state": "takeoffStand" + }, + { + "var": "isTakeoffRun", + "state": "TAKEOFFRUN" + }, + { + "var": "isInAirStand", + "state": "inAirStand" + }, + { + "var": "isInAirRun", + "state": "INAIRRUN" + }, + { + "var": "isMovingRightHmd", + "state": "strafeRightHmd" + }, + { + "var": "isMovingLeftHmd", + "state": "strafeLeftHmd" + } + ] + }, + { + "id": "idleToWalkFwd", + "interpTarget": 12, + "interpDuration": 8, + "transitions": [ + { + "var": "idleToWalkFwdOnDone", + "state": "WALKFWD" + }, + { + "var": "isNotMoving", + "state": "idle" + }, + { + "var": "isMovingBackward", + "state": "WALKBWD" + }, + { + "var": "isMovingRight", + "state": "STRAFERIGHT" + }, + { + "var": "isMovingLeft", + "state": "STRAFELEFT" + }, + { + "var": "isTurningRight", + "state": "turnRight" + }, + { + "var": "isTurningLeft", + "state": "turnLeft" + }, + { + "var": "isFlying", + "state": "fly" + }, + { + "var": "isTakeoffStand", + "state": "takeoffStand" + }, + { + "var": "isTakeoffRun", + "state": "TAKEOFFRUN" + }, + { + "var": "isInAirStand", + "state": "inAirStand" + }, + { + "var": "isInAirRun", + "state": "INAIRRUN" + }, + { + "var": "isMovingRightHmd", + "state": "strafeRightHmd" + }, + { + "var": "isMovingLeftHmd", + "state": "strafeLeftHmd" + } + ] + }, + { + "id": "idleSettle", + "interpTarget": 15, + "interpDuration": 8, + "interpType": "snapshotPrev", + "transitions": [ + { + "var": "idleSettleOnDone", + "state": "idle" + }, + { + "var": "isMovingForward", + "state": "WALKFWD" + }, + { + "var": "isMovingBackward", + "state": "WALKBWD" + }, + { + "var": "isMovingRight", + "state": "STRAFERIGHT" + }, + { + "var": "isMovingLeft", + "state": "STRAFELEFT" + }, + { + "var": "isMovingRightHmd", + "state": "strafeRightHmd" + }, + { + "var": "isMovingLeftHmd", + "state": "strafeLeftHmd" + }, + { + "var": "isTurningRight", + "state": "turnRight" + }, + { + "var": "isTurningLeft", + "state": "turnLeft" + }, + { + "var": "isFlying", + "state": "fly" + }, + { + "var": "isTakeoffStand", + "state": "takeoffStand" + }, + { + "var": "isTakeoffRun", + "state": "TAKEOFFRUN" + }, + { + "var": "isInAirStand", + "state": "inAirStand" + }, + { + "var": "isInAirRun", + "state": "INAIRRUN" + } + ] + }, + { + "id": "WALKFWD", + "interpTarget": 35, + "interpDuration": 10, + "interpType": "snapshotPrev", + "transitions": [ + { + "var": "isNotMoving", + "state": "idleSettle" + }, + { + "var": "isMovingBackward", + "state": "WALKBWD" + }, + { + "var": "isMovingRight", + "state": "STRAFERIGHT" + }, + { + "var": "isMovingLeft", + "state": "STRAFELEFT" + }, + { + "var": "isTurningRight", + "state": "turnRight" + }, + { + "var": "isTurningLeft", + "state": "turnLeft" + }, + { + "var": "isFlying", + "state": "fly" + }, + { + "var": "isTakeoffStand", + "state": "takeoffStand" + }, + { + "var": "isTakeoffRun", + "state": "TAKEOFFRUN" + }, + { + "var": "isInAirStand", + "state": "inAirStand" + }, + { + "var": "isInAirRun", + "state": "INAIRRUN" + }, + { + "var": "isMovingRightHmd", + "state": "strafeRightHmd" + }, + { + "var": "isMovingLeftHmd", + "state": "strafeLeftHmd" + } + ] + }, + { + "id": "WALKBWD", + "interpTarget": 35, + "interpDuration": 10, + "interpType": "snapshotPrev", + "transitions": [ + { + "var": "isNotMoving", + "state": "idleSettle" + }, + { + "var": "isMovingForward", + "state": "WALKFWD" + }, + { + "var": "isMovingRight", + "state": "STRAFERIGHT" + }, + { + "var": "isMovingLeft", + "state": "STRAFELEFT" + }, + { + "var": "isTurningRight", + "state": "turnRight" + }, + { + "var": "isTurningLeft", + "state": "turnLeft" + }, + { + "var": "isFlying", + "state": "fly" + }, + { + "var": "isTakeoffStand", + "state": "takeoffStand" + }, + { + "var": "isTakeoffRun", + "state": "TAKEOFFRUN" + }, + { + "var": "isInAirStand", + "state": "inAirStand" + }, + { + "var": "isInAirRun", + "state": "INAIRRUN" + }, + { + "var": "isMovingRightHmd", + "state": "strafeRightHmd" + }, + { + "var": "isMovingLeftHmd", + "state": "strafeLeftHmd" + } + ] + }, + { + "id": "STRAFERIGHT", + "interpTarget": 25, + "interpDuration": 8, + "interpType": "snapshotPrev", + "transitions": [ + { + "var": "isNotMoving", + "state": "idleSettle" + }, + { + "var": "isMovingForward", + "state": "WALKFWD" + }, + { + "var": "isMovingBackward", + "state": "WALKBWD" + }, + { + "var": "isMovingLeft", + "state": "STRAFELEFT" + }, + { + "var": "isTurningRight", + "state": "turnRight" + }, + { + "var": "isTurningLeft", + "state": "turnLeft" + }, + { + "var": "isFlying", + "state": "fly" + }, + { + "var": "isTakeoffStand", + "state": "takeoffStand" + }, + { + "var": "isTakeoffRun", + "state": "TAKEOFFRUN" + }, + { + "var": "isInAirStand", + "state": "inAirStand" + }, + { + "var": "isInAirRun", + "state": "INAIRRUN" + }, + { + "var": "isMovingRightHmd", + "state": "strafeRightHmd" + }, + { + "var": "isMovingLeftHmd", + "state": "strafeLeftHmd" + } + ] + }, + { + "id": "STRAFELEFT", + "interpTarget": 25, + "interpDuration": 8, + "interpType": "snapshotPrev", + "transitions": [ + { + "var": "isNotMoving", + "state": "idleSettle" + }, + { + "var": "isMovingForward", + "state": "WALKFWD" + }, + { + "var": "isMovingBackward", + "state": "WALKBWD" + }, + { + "var": "isMovingRight", + "state": "STRAFERIGHT" + }, + { + "var": "isTurningRight", + "state": "turnRight" + }, + { + "var": "isTurningLeft", + "state": "turnLeft" + }, + { + "var": "isFlying", + "state": "fly" + }, + { + "var": "isTakeoffStand", + "state": "takeoffStand" + }, + { + "var": "isTakeoffRun", + "state": "TAKEOFFRUN" + }, + { + "var": "isInAirStand", + "state": "inAirStand" + }, + { + "var": "isInAirRun", + "state": "INAIRRUN" + }, + { + "var": "isMovingRightHmd", + "state": "strafeRightHmd" + }, + { + "var": "isMovingLeftHmd", + "state": "strafeLeftHmd" + } + ] + }, + { + "id": "turnRight", + "interpTarget": 6, + "interpDuration": 8, + "transitions": [ + { + "var": "isNotTurning", + "state": "idle" + }, + { + "var": "isMovingForward", + "state": "WALKFWD" + }, + { + "var": "isMovingBackward", + "state": "WALKBWD" + }, + { + "var": "isMovingRight", + "state": "STRAFERIGHT" + }, + { + "var": "isMovingLeft", + "state": "STRAFELEFT" + }, + { + "var": "isTurningLeft", + "state": "turnLeft" + }, + { + "var": "isFlying", + "state": "fly" + }, + { + "var": "isTakeoffStand", + "state": "takeoffStand" + }, + { + "var": "isTakeoffRun", + "state": "TAKEOFFRUN" + }, + { + "var": "isInAirStand", + "state": "inAirStand" + }, + { + "var": "isInAirRun", + "state": "INAIRRUN" + }, + { + "var": "isMovingRightHmd", + "state": "strafeRightHmd" + }, + { + "var": "isMovingLeftHmd", + "state": "strafeLeftHmd" + } + ] + }, + { + "id": "turnLeft", + "interpTarget": 6, + "interpDuration": 8, + "transitions": [ + { + "var": "isNotTurning", + "state": "idle" + }, + { + "var": "isMovingForward", + "state": "WALKFWD" + }, + { + "var": "isMovingBackward", + "state": "WALKBWD" + }, + { + "var": "isMovingRight", + "state": "STRAFERIGHT" + }, + { + "var": "isMovingLeft", + "state": "STRAFELEFT" + }, + { + "var": "isTurningRight", + "state": "turnRight" + }, + { + "var": "isFlying", + "state": "fly" + }, + { + "var": "isTakeoffStand", + "state": "takeoffStand" + }, + { + "var": "isTakeoffRun", + "state": "TAKEOFFRUN" + }, + { + "var": "isInAirStand", + "state": "inAirStand" + }, + { + "var": "isInAirRun", + "state": "INAIRRUN" + }, + { + "var": "isMovingRightHmd", + "state": "strafeRightHmd" + }, + { + "var": "isMovingLeftHmd", + "state": "strafeLeftHmd" + } + ] + }, + { + "id": "strafeRightHmd", + "interpTarget": 5, + "interpDuration": 8, + "interpType": "snapshotPrev", + "transitions": [ + { + "var": "isNotMoving", + "state": "idleSettle" + }, + { + "var": "isMovingForward", + "state": "WALKFWD" + }, + { + "var": "isMovingBackward", + "state": "WALKBWD" + }, + { + "var": "isMovingLeftHmd", + "state": "strafeLeftHmd" + }, + { + "var": "isMovingRight", + "state": "STRAFERIGHT" + }, + { + "var": "isMovingLeft", + "state": "STRAFELEFT" + }, + { + "var": "isTurningRight", + "state": "turnRight" + }, + { + "var": "isTurningLeft", + "state": "turnLeft" + }, + { + "var": "isFlying", + "state": "fly" + }, + { + "var": "isTakeoffStand", + "state": "takeoffStand" + }, + { + "var": "isTakeoffRun", + "state": "TAKEOFFRUN" + }, + { + "var": "isInAirStand", + "state": "inAirStand" + }, + { + "var": "isInAirRun", + "state": "INAIRRUN" + } + ] + }, + { + "id": "strafeLeftHmd", + "interpTarget": 5, + "interpDuration": 8, + "interpType": "snapshotPrev", + "transitions": [ + { + "var": "isNotMoving", + "state": "idleSettle" + }, + { + "var": "isMovingForward", + "state": "WALKFWD" + }, + { + "var": "isMovingBackward", + "state": "WALKBWD" + }, + { + "var": "isMovingRightHmd", + "state": "strafeRightHmd" + }, + { + "var": "isMovingRight", + "state": "STRAFERIGHT" + }, + { + "var": "isMovingLeft", + "state": "STRAFELEFT" + }, + { + "var": "isTurningRight", + "state": "turnRight" + }, + { + "var": "isTurningLeft", + "state": "turnLeft" + }, + { + "var": "isFlying", + "state": "fly" + }, + { + "var": "isTakeoffStand", + "state": "takeoffStand" + }, + { + "var": "isTakeoffRun", + "state": "TAKEOFFRUN" + }, + { + "var": "isInAirStand", + "state": "inAirStand" + }, + { + "var": "isInAirRun", + "state": "INAIRRUN" + } + ] + }, + { + "id": "fly", + "interpTarget": 6, + "interpDuration": 6, + "transitions": [ + { + "var": "isNotFlying", + "state": "idleSettle" + } + ] + }, + { + "id": "takeoffStand", + "interpTarget": 2, + "interpDuration": 2, + "transitions": [ + { + "var": "isNotTakeoff", + "state": "inAirStand" + } + ] + }, + { + "id": "TAKEOFFRUN", + "interpTarget": 2, + "interpDuration": 2, + "transitions": [ + { + "var": "isNotTakeoff", + "state": "INAIRRUN" + } + ] + }, + { + "id": "inAirStand", + "interpTarget": 3, + "interpDuration": 3, + "interpType": "snapshotPrev", + "transitions": [ + { + "var": "isNotInAir", + "state": "landStandImpact" + } + ] + }, + { + "id": "INAIRRUN", + "interpTarget": 3, + "interpDuration": 3, + "interpType": "snapshotPrev", + "transitions": [ + { + "var": "isNotInAir", + "state": "WALKFWD" + } + ] + }, + { + "id": "landStandImpact", + "interpTarget": 1, + "interpDuration": 1, + "transitions": [ + { + "var": "isFlying", + "state": "fly" + }, + { + "var": "isTakeoffStand", + "state": "takeoffStand" + }, + { + "var": "isTakeoffRun", + "state": "TAKEOFFRUN" + }, + { + "var": "landStandImpactOnDone", + "state": "landStand" + } + ] + }, + { + "id": "landStand", + "interpTarget": 1, + "interpDuration": 1, + "transitions": [ + { + "var": "isMovingForward", + "state": "WALKFWD" + }, + { + "var": "isMovingBackward", + "state": "WALKBWD" + }, + { + "var": "isMovingRight", + "state": "STRAFERIGHT" + }, + { + "var": "isMovingLeft", + "state": "STRAFELEFT" + }, + { + "var": "isTurningRight", + "state": "turnRight" + }, + { + "var": "isTurningLeft", + "state": "turnLeft" + }, + { + "var": "isFlying", + "state": "fly" + }, + { + "var": "isTakeoffStand", + "state": "takeoffStand" + }, + { + "var": "isTakeoffRun", + "state": "TAKEOFFRUN" + }, + { + "var": "isInAirStand", + "state": "inAirStand" + }, + { + "var": "isInAirRun", + "state": "INAIRRUN" + }, + { + "var": "landStandOnDone", + "state": "idle" + }, + { + "var": "isMovingRightHmd", + "state": "strafeRightHmd" + }, + { + "var": "isMovingLeftHmd", + "state": "strafeLeftHmd" + } + ] + }, + { + "id": "LANDRUN", + "interpTarget": 2, + "interpDuration": 2, + "transitions": [ + { + "var": "isFlying", + "state": "fly" + }, + { + "var": "isTakeoffStand", + "state": "takeoffStand" + }, + { + "var": "isTakeoffRun", + "state": "TAKEOFFRUN" + }, + { + "var": "landRunOnDone", + "state": "WALKFWD" + } + ] + } + ] }, "children": [ { - "id": "walkFwdShort_c", - "type": "clip", + "id": "idle", + "type": "stateMachine", "data": { - "url": "qrc:///avatar/animations/walk_short_fwd.fbx", - "startFrame": 0.0, - "endFrame": 39.0, - "timeScale": 1.0, - "loopFlag": true + "currentState": "idleStand", + "states": [ + { + "id": "idleStand", + "interpTarget": 6, + "interpDuration": 10, + "transitions": [ + { + "var": "isTalking", + "state": "idleTalk" + } + ] + }, + { + "id": "idleTalk", + "interpTarget": 6, + "interpDuration": 10, + "transitions": [ + { + "var": "notIsTalking", + "state": "idleStand" + } + ] + } + ] }, - "children": [] + "children": [ + { + "id": "idleStand", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/idle.fbx", + "startFrame": 0.0, + "endFrame": 300.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "idleTalk", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/talk.fbx", + "startFrame": 0.0, + "endFrame": 800.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + } + ] }, { - "id": "walkFwdNormal_c", - "type": "clip", + "id": "WALKFWD", + "type": "blendLinearMove", "data": { - "url": "qrc:///avatar/animations/walk_fwd.fbx", - "startFrame": 0.0, - "endFrame": 30.0, - "timeScale": 1.0, - "loopFlag": true + "alpha": 0.0, + "desiredSpeed": 1.4, + "characteristicSpeeds": [ 0.5, 1.8, 2.3, 3.2, 4.5 ], + "alphaVar": "moveForwardAlpha", + "desiredSpeedVar": "moveForwardSpeed" }, - "children": [] + "children": [ + { + "id": "walkFwdShort_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/walk_short_fwd.fbx", + "startFrame": 0.0, + "endFrame": 39.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "walkFwdNormal_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/walk_fwd.fbx", + "startFrame": 0.0, + "endFrame": 30.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "walkFwdFast_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/walk_fwd_fast.fbx", + "startFrame": 0.0, + "endFrame": 25.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "walkFwdJog_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jog_fwd.fbx", + "startFrame": 0.0, + "endFrame": 25.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "walkFwdRun_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/run_fwd.fbx", + "startFrame": 0.0, + "endFrame": 21.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + } + ] }, { - "id": "walkFwdFast_c", + "id": "idleToWalkFwd", "type": "clip", "data": { - "url": "qrc:///avatar/animations/walk_fwd_fast.fbx", - "startFrame": 0.0, - "endFrame": 25.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - }, - { - "id": "walkFwdJog_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/jog_fwd.fbx", - "startFrame": 0.0, - "endFrame": 25.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - }, - { - "id": "walkFwdRun_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/run_fwd.fbx", - "startFrame": 0.0, - "endFrame": 21.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - } - ] - }, - { - "id": "idleToWalkFwd", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/idle_to_walk.fbx", - "startFrame": 1.0, - "endFrame": 13.0, - "timeScale": 1.0, - "loopFlag": false - }, - "children": [] - }, - { - "id": "idleSettle", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/settle_to_idle.fbx", - "startFrame": 1.0, - "endFrame": 59.0, - "timeScale": 1.0, - "loopFlag": false - }, - "children": [] - }, - { - "id": "WALKBWD", - "type": "blendLinearMove", - "data": { - "alpha": 0.0, - "desiredSpeed": 1.4, - "characteristicSpeeds": [ 0.6, 1.6, 2.3, 3.1 ], - "alphaVar": "moveBackwardAlpha", - "desiredSpeedVar": "moveBackwardSpeed" - }, - "children": [ - { - "id": "walkBwdShort_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/walk_short_bwd.fbx", - "startFrame": 0.0, - "endFrame": 38.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - }, - { - "id": "walkBwdFast_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/walk_bwd_fast.fbx", - "startFrame": 0.0, - "endFrame": 27.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - }, - { - "id": "jogBwd_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/jog_bwd.fbx", - "startFrame": 0.0, - "endFrame": 24.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - }, - { - "id": "runBwd_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/run_bwd.fbx", - "startFrame": 0.0, - "endFrame": 16.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - } - ] - }, - { - "id": "turnLeft", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/turn_left.fbx", - "startFrame": 0.0, - "endFrame": 32.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - }, - { - "id": "turnRight", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/turn_left.fbx", - "startFrame": 0.0, - "endFrame": 32.0, - "timeScale": 1.0, - "loopFlag": true, - "mirrorFlag": true - }, - "children": [] - }, - { - "id": "STRAFELEFT", - "type": "blendLinearMove", - "data": { - "alpha": 0.0, - "desiredSpeed": 1.4, - "characteristicSpeeds": [ 0.1, 0.5, 1.0, 2.6, 3.0 ], - "alphaVar": "moveLateralAlpha", - "desiredSpeedVar": "moveLateralSpeed" - }, - "children": [ - { - "id": "strafeLeftShortStep_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/side_step_short_left.fbx", - "startFrame": 0.0, - "endFrame": 29.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - }, - { - "id": "strafeLeftStep_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/side_step_left.fbx", - "startFrame": 0.0, - "endFrame": 20.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - }, - { - "id": "strafeLeftWalk_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/walk_left.fbx", - "startFrame": 0.0, - "endFrame": 35.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - }, - { - "id": "strafeLeftWalkFast_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/walk_left_fast.fbx", - "startFrame": 0.0, - "endFrame": 21.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - }, - { - "id": "strafeLeftJog_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/jog_left.fbx", - "startFrame": 0.0, - "endFrame": 24.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - } - ] - }, - { - "id": "STRAFERIGHT", - "type": "blendLinearMove", - "data": { - "alpha": 0.0, - "desiredSpeed": 1.4, - "characteristicSpeeds": [ 0.1, 0.5, 1.0, 2.6, 3.0 ], - "alphaVar": "moveLateralAlpha", - "desiredSpeedVar": "moveLateralSpeed" - }, - "children": [ - { - "id": "strafeRightShortStep_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/side_step_short_left.fbx", - "startFrame": 0.0, - "endFrame": 29.0, - "timeScale": 1.0, - "loopFlag": true, - "mirrorFlag": true - }, - "children": [] - }, - { - "id": "strafeRightStep_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/side_step_left.fbx", - "startFrame": 0.0, - "endFrame": 20.0, - "timeScale": 1.0, - "loopFlag": true, - "mirrorFlag": true - }, - "children": [] - }, - { - "id": "strafeRightWalk_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/walk_left.fbx", - "startFrame": 0.0, - "endFrame": 35.0, - "timeScale": 1.0, - "loopFlag": true, - "mirrorFlag": true - }, - "children": [] - }, - { - "id": "strafeRightFast_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/walk_left_fast.fbx", - "startFrame": 0.0, - "endFrame": 21.0, - "timeScale": 1.0, - "loopFlag": true, - "mirrorFlag": true - }, - "children": [] - }, - { - "id": "strafeRightJog_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/jog_left.fbx", - "startFrame": 0.0, - "endFrame": 24.0, - "timeScale": 1.0, - "loopFlag": true, - "mirrorFlag": true - }, - "children": [] - } - ] - }, - { - "id": "strafeLeftHmd", - "type": "blendLinearMove", - "data": { - "alpha": 0.0, - "desiredSpeed": 1.4, - "characteristicSpeeds": [ 0, 0.5, 2.5 ], - "alphaVar": "moveLateralAlpha", - "desiredSpeedVar": "moveLateralSpeed" - }, - "children": [ - { - "id": "stepLeftShort_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/side_step_short_left.fbx", - "startFrame": 0.0, - "endFrame": 29.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - }, - { - "id": "stepLeft_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/side_step_left.fbx", - "startFrame": 0.0, - "endFrame": 20.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - }, - { - "id": "strafeLeftAnim_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/side_step_left_fast.fbx", - "startFrame": 0.0, - "endFrame": 16.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - } - ] - }, - { - "id": "strafeRightHmd", - "type": "blendLinearMove", - "data": { - "alpha": 0.0, - "desiredSpeed": 1.4, - "characteristicSpeeds": [ 0, 0.5, 2.5 ], - "alphaVar": "moveLateralAlpha", - "desiredSpeedVar": "moveLateralSpeed" - }, - "children": [ - { - "id": "stepRightShort_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/side_step_short_left.fbx", - "startFrame": 0.0, - "endFrame": 29.0, - "timeScale": 1.0, - "loopFlag": true, - "mirrorFlag": true - }, - "children": [] - }, - { - "id": "stepRight_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/side_step_left.fbx", - "startFrame": 0.0, - "endFrame": 20.0, - "timeScale": 1.0, - "loopFlag": true, - "mirrorFlag": true - }, - "children": [] - }, - { - "id": "strafeRightAnim_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/side_step_left_fast.fbx", - "startFrame": 0.0, - "endFrame": 16.0, - "timeScale": 1.0, - "loopFlag": true, - "mirrorFlag": true - }, - "children": [] - } - ] - }, - { - "id": "fly", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/fly.fbx", - "startFrame": 1.0, - "endFrame": 80.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - }, - { - "id": "takeoffStand", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/jump_standing_launch.fbx", - "startFrame": 2.0, - "endFrame": 16.0, - "timeScale": 1.0, - "loopFlag": false - }, - "children": [] - }, - { - "id": "TAKEOFFRUN", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/jump_running_launch_land.fbx", - "startFrame": 4.0, - "endFrame": 15.0, - "timeScale": 1.0, - "loopFlag": false - }, - "children": [] - }, - { - "id": "inAirStand", - "type": "blendLinear", - "data": { - "alpha": 0.0, - "alphaVar": "inAirAlpha" - }, - "children": [ - { - "id": "inAirStandPreApex", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/jump_standing_apex.fbx", - "startFrame": 0.0, - "endFrame": 0.0, - "timeScale": 1.0, - "loopFlag": false - }, - "children": [] - }, - { - "id": "inAirStandApex", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/jump_standing_apex.fbx", + "url": "qrc:///avatar/animations/idle_to_walk.fbx", "startFrame": 1.0, - "endFrame": 1.0, + "endFrame": 13.0, "timeScale": 1.0, "loopFlag": false }, "children": [] }, { - "id": "inAirStandPostApex", + "id": "idleSettle", "type": "clip", "data": { - "url": "qrc:///avatar/animations/jump_standing_apex.fbx", - "startFrame": 2.0, - "endFrame": 2.0, + "url": "qrc:///avatar/animations/settle_to_idle.fbx", + "startFrame": 1.0, + "endFrame": 59.0, "timeScale": 1.0, "loopFlag": false }, "children": [] - } - ] - }, - { - "id": "INAIRRUN", - "type": "blendLinear", - "data": { - "alpha": 0.0, - "alphaVar": "inAirAlpha" - }, - "children": [ + }, { - "id": "inAirRunPreApex", + "id": "WALKBWD", + "type": "blendLinearMove", + "data": { + "alpha": 0.0, + "desiredSpeed": 1.4, + "characteristicSpeeds": [ 0.6, 1.6, 2.3, 3.1 ], + "alphaVar": "moveBackwardAlpha", + "desiredSpeedVar": "moveBackwardSpeed" + }, + "children": [ + { + "id": "walkBwdShort_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/walk_short_bwd.fbx", + "startFrame": 0.0, + "endFrame": 38.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "walkBwdFast_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/walk_bwd_fast.fbx", + "startFrame": 0.0, + "endFrame": 27.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "jogBwd_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jog_bwd.fbx", + "startFrame": 0.0, + "endFrame": 24.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "runBwd_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/run_bwd.fbx", + "startFrame": 0.0, + "endFrame": 16.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + } + ] + }, + { + "id": "turnLeft", "type": "clip", "data": { - "url": "qrc:///avatar/animations/jump_running_launch_land.fbx", - "startFrame": 16.0, + "url": "qrc:///avatar/animations/turn_left.fbx", + "startFrame": 0.0, + "endFrame": 32.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "turnRight", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/turn_left.fbx", + "startFrame": 0.0, + "endFrame": 32.0, + "timeScale": 1.0, + "loopFlag": true, + "mirrorFlag": true + }, + "children": [] + }, + { + "id": "STRAFELEFT", + "type": "blendLinearMove", + "data": { + "alpha": 0.0, + "desiredSpeed": 1.4, + "characteristicSpeeds": [ 0.1, 0.5, 1.0, 2.6, 3.0 ], + "alphaVar": "moveLateralAlpha", + "desiredSpeedVar": "moveLateralSpeed" + }, + "children": [ + { + "id": "strafeLeftShortStep_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/side_step_short_left.fbx", + "startFrame": 0.0, + "endFrame": 29.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "strafeLeftStep_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/side_step_left.fbx", + "startFrame": 0.0, + "endFrame": 20.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "strafeLeftWalk_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/walk_left.fbx", + "startFrame": 0.0, + "endFrame": 35.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "strafeLeftWalkFast_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/walk_left_fast.fbx", + "startFrame": 0.0, + "endFrame": 21.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "strafeLeftJog_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jog_left.fbx", + "startFrame": 0.0, + "endFrame": 24.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + } + ] + }, + { + "id": "STRAFERIGHT", + "type": "blendLinearMove", + "data": { + "alpha": 0.0, + "desiredSpeed": 1.4, + "characteristicSpeeds": [ 0.1, 0.5, 1.0, 2.6, 3.0 ], + "alphaVar": "moveLateralAlpha", + "desiredSpeedVar": "moveLateralSpeed" + }, + "children": [ + { + "id": "strafeRightShortStep_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/side_step_short_left.fbx", + "startFrame": 0.0, + "endFrame": 29.0, + "timeScale": 1.0, + "loopFlag": true, + "mirrorFlag": true + }, + "children": [] + }, + { + "id": "strafeRightStep_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/side_step_left.fbx", + "startFrame": 0.0, + "endFrame": 20.0, + "timeScale": 1.0, + "loopFlag": true, + "mirrorFlag": true + }, + "children": [] + }, + { + "id": "strafeRightWalk_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/walk_left.fbx", + "startFrame": 0.0, + "endFrame": 35.0, + "timeScale": 1.0, + "loopFlag": true, + "mirrorFlag": true + }, + "children": [] + }, + { + "id": "strafeRightFast_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/walk_left_fast.fbx", + "startFrame": 0.0, + "endFrame": 21.0, + "timeScale": 1.0, + "loopFlag": true, + "mirrorFlag": true + }, + "children": [] + }, + { + "id": "strafeRightJog_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jog_left.fbx", + "startFrame": 0.0, + "endFrame": 24.0, + "timeScale": 1.0, + "loopFlag": true, + "mirrorFlag": true + }, + "children": [] + } + ] + }, + { + "id": "strafeLeftHmd", + "type": "blendLinearMove", + "data": { + "alpha": 0.0, + "desiredSpeed": 1.4, + "characteristicSpeeds": [ 0, 0.5, 2.5 ], + "alphaVar": "moveLateralAlpha", + "desiredSpeedVar": "moveLateralSpeed" + }, + "children": [ + { + "id": "stepLeftShort_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/side_step_short_left.fbx", + "startFrame": 0.0, + "endFrame": 29.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "stepLeft_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/side_step_left.fbx", + "startFrame": 0.0, + "endFrame": 20.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "strafeLeftAnim_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/side_step_left_fast.fbx", + "startFrame": 0.0, + "endFrame": 16.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + } + ] + }, + { + "id": "strafeRightHmd", + "type": "blendLinearMove", + "data": { + "alpha": 0.0, + "desiredSpeed": 1.4, + "characteristicSpeeds": [ 0, 0.5, 2.5 ], + "alphaVar": "moveLateralAlpha", + "desiredSpeedVar": "moveLateralSpeed" + }, + "children": [ + { + "id": "stepRightShort_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/side_step_short_left.fbx", + "startFrame": 0.0, + "endFrame": 29.0, + "timeScale": 1.0, + "loopFlag": true, + "mirrorFlag": true + }, + "children": [] + }, + { + "id": "stepRight_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/side_step_left.fbx", + "startFrame": 0.0, + "endFrame": 20.0, + "timeScale": 1.0, + "loopFlag": true, + "mirrorFlag": true + }, + "children": [] + }, + { + "id": "strafeRightAnim_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/side_step_left_fast.fbx", + "startFrame": 0.0, + "endFrame": 16.0, + "timeScale": 1.0, + "loopFlag": true, + "mirrorFlag": true + }, + "children": [] + } + ] + }, + { + "id": "fly", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/fly.fbx", + "startFrame": 1.0, + "endFrame": 80.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "takeoffStand", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jump_standing_launch.fbx", + "startFrame": 2.0, "endFrame": 16.0, "timeScale": 1.0, "loopFlag": false @@ -2099,66 +2010,146 @@ "children": [] }, { - "id": "inAirRunApex", + "id": "TAKEOFFRUN", "type": "clip", "data": { "url": "qrc:///avatar/animations/jump_running_launch_land.fbx", - "startFrame": 22.0, - "endFrame": 22.0, + "startFrame": 4.0, + "endFrame": 15.0, "timeScale": 1.0, "loopFlag": false }, "children": [] }, { - "id": "inAirRunPostApex", + "id": "inAirStand", + "type": "blendLinear", + "data": { + "alpha": 0.0, + "alphaVar": "inAirAlpha" + }, + "children": [ + { + "id": "inAirStandPreApex", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jump_standing_apex.fbx", + "startFrame": 0.0, + "endFrame": 0.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] + }, + { + "id": "inAirStandApex", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jump_standing_apex.fbx", + "startFrame": 1.0, + "endFrame": 1.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] + }, + { + "id": "inAirStandPostApex", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jump_standing_apex.fbx", + "startFrame": 2.0, + "endFrame": 2.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] + } + ] + }, + { + "id": "INAIRRUN", + "type": "blendLinear", + "data": { + "alpha": 0.0, + "alphaVar": "inAirAlpha" + }, + "children": [ + { + "id": "inAirRunPreApex", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jump_running_launch_land.fbx", + "startFrame": 16.0, + "endFrame": 16.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] + }, + { + "id": "inAirRunApex", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jump_running_launch_land.fbx", + "startFrame": 22.0, + "endFrame": 22.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] + }, + { + "id": "inAirRunPostApex", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jump_running_launch_land.fbx", + "startFrame": 33.0, + "endFrame": 33.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] + } + ] + }, + { + "id": "landStandImpact", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jump_standing_land_settle.fbx", + "startFrame": 1.0, + "endFrame": 6.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] + }, + { + "id": "landStand", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jump_standing_land_settle.fbx", + "startFrame": 6.0, + "endFrame": 68.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] + }, + { + "id": "LANDRUN", "type": "clip", "data": { "url": "qrc:///avatar/animations/jump_running_launch_land.fbx", - "startFrame": 33.0, - "endFrame": 33.0, + "startFrame": 29.0, + "endFrame": 40.0, "timeScale": 1.0, "loopFlag": false }, "children": [] } ] - }, - { - "id": "landStandImpact", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/jump_standing_land_settle.fbx", - "startFrame": 1.0, - "endFrame": 6.0, - "timeScale": 1.0, - "loopFlag": false - }, - "children": [] - }, - { - "id": "landStand", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/jump_standing_land_settle.fbx", - "startFrame": 6.0, - "endFrame": 68.0, - "timeScale": 1.0, - "loopFlag": false - }, - "children": [] - }, - { - "id": "LANDRUN", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/jump_running_launch_land.fbx", - "startFrame": 29.0, - "endFrame": 40.0, - "timeScale": 1.0, - "loopFlag": false - }, - "children": [] } ] } diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 2401bf5315..de773f2d20 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -4679,7 +4679,6 @@ void setupCpuMonitorThread() { void Application::idle() { PerformanceTimer perfTimer("idle"); - qCDebug(interfaceapp) << "idle called"; // Update the deadlock watchdog updateHeartbeat(); diff --git a/libraries/animation/src/AnimInverseKinematics.cpp b/libraries/animation/src/AnimInverseKinematics.cpp index e5509dc43d..8d2ba0fd78 100644 --- a/libraries/animation/src/AnimInverseKinematics.cpp +++ b/libraries/animation/src/AnimInverseKinematics.cpp @@ -886,7 +886,7 @@ const AnimPoseVec& AnimInverseKinematics::overlay(const AnimVariantMap& animVars if (dt > MAX_OVERLAY_DT) { dt = MAX_OVERLAY_DT; } - + if (_relativePoses.size() != underPoses.size()) { loadPoses(underPoses); } else { @@ -973,8 +973,8 @@ const AnimPoseVec& AnimInverseKinematics::overlay(const AnimVariantMap& animVars ::blend(1, &prevHipsAbsPose, &absPose, alpha, &absPose); } - _relativePoses[_hipsIndex] = parentAbsPose.inverse() * absPose; - _relativePoses[_hipsIndex].scale() = glm::vec3(1.0f); + //_relativePoses[_hipsIndex] = parentAbsPose.inverse() * absPose; + //_relativePoses[_hipsIndex].scale() = glm::vec3(1.0f); } // if there is an active jointChainInfo for the hips store the post shifted hips into it. @@ -1041,10 +1041,13 @@ const AnimPoseVec& AnimInverseKinematics::overlay(const AnimVariantMap& animVars preconditionRelativePosesToAvoidLimbLock(context, targets); - solve(context, targets, dt, jointChainInfoVec); + //qCDebug(animation) << "hips before ccd" << _relativePoses[_hipsIndex]; + //solve(context, targets, dt, jointChainInfoVec); + //qCDebug(animation) << "hips after ccd" << _relativePoses[_hipsIndex]; + } } - + if (context.getEnableDebugDrawIKConstraints()) { debugDrawConstraints(context); } diff --git a/libraries/animation/src/AnimSplineIK.cpp b/libraries/animation/src/AnimSplineIK.cpp index fe54aa5fe7..23bf8b2800 100644 --- a/libraries/animation/src/AnimSplineIK.cpp +++ b/libraries/animation/src/AnimSplineIK.cpp @@ -48,6 +48,22 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const // evalute underPoses AnimPoseVec underPoses = _children[0]->evaluate(animVars, context, dt, triggersOut); _poses = underPoses; + + // now we override the hips relative pose based on the hips target that has been set. + //////////////////////////////////////////////////// + if (_poses.size() > 0) { + AnimPose hipsUnderPose = _skeleton->getAbsolutePose(_hipsIndex, _poses); + glm::quat hipsTargetRotation = animVars.lookupRigToGeometry("hipsRotation", hipsUnderPose.rot()); + glm::vec3 hipsTargetTranslation = animVars.lookupRigToGeometry("hipsPosition", hipsUnderPose.trans()); + AnimPose absHipsTargetPose(hipsTargetRotation, hipsTargetTranslation); + + int hipsParentIndex = _skeleton->getParentIndex(_hipsIndex); + AnimPose hipsParentAbsPose = _skeleton->getAbsolutePose(hipsParentIndex, _poses); + + _poses[_hipsIndex] = hipsParentAbsPose.inverse() * absHipsTargetPose; + _poses[_hipsIndex].scale() = glm::vec3(1.0f); + } + ////////////////////////////////////////////////////////////////////////////////// // check to see if we actually need absolute poses. AnimPoseVec absolutePoses; @@ -65,7 +81,7 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const AnimPose origSpine1 = _skeleton->getAbsolutePose(_skeleton->nameToJointIndex("Spine1"),_poses); //origSpine2PoseRel = origSpine1.inverse() * origSpine2; //qCDebug(animation) << "origSpine2Pose: " << origSpine2Pose.rot(); - qCDebug(animation) << "original relative spine2 " << origSpine2PoseAbs; + //qCDebug(animation) << "original relative spine2 " << origSpine2PoseAbs; } @@ -116,8 +132,8 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const targetSpine2 = AnimPose(rotation3, afterSolveSpine2.trans()); finalSpine2 = afterSolveSpine1.inverse() * targetSpine2; - qCDebug(animation) << "relative spine2 after solve" << afterSolveSpine2Rel; - qCDebug(animation) << "relative spine2 orig" << originalSpine2Relative; + //qCDebug(animation) << "relative spine2 after solve" << afterSolveSpine2Rel; + //qCDebug(animation) << "relative spine2 orig" << originalSpine2Relative; AnimPose latestSpine2Relative(originalSpine2Relative.rot(), afterSolveSpine2Rel.trans()); //jointChain.setRelativePoseAtJointIndex(jointIndex2, finalSpine2); jointChain.outputRelativePoses(_poses); @@ -146,7 +162,7 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const glm::quat rotation2 = animVars.lookupRigToGeometry("spine2Rotation", absPose2.rot()); glm::vec3 translation2 = animVars.lookupRigToGeometry("spine2Position", absPose2.trans()); float weight2 = animVars.lookup("spine2Weight", "2.0"); - qCDebug(animation) << "rig to geometry" << rotation2; + // qCDebug(animation) << "rig to geometry" << rotation2; //target2.setPose(rotation2, translation2); target2.setPose(targetSpine2.rot(), targetSpine2.trans()); diff --git a/libraries/animation/src/AnimTwoBoneIK.cpp b/libraries/animation/src/AnimTwoBoneIK.cpp index 5df98df969..31397157ac 100644 --- a/libraries/animation/src/AnimTwoBoneIK.cpp +++ b/libraries/animation/src/AnimTwoBoneIK.cpp @@ -79,6 +79,7 @@ const AnimPoseVec& AnimTwoBoneIK::evaluate(const AnimVariantMap& animVars, const // determine if we should interpolate bool enabled = animVars.lookup(_enabledVar, _enabled); + // qCDebug(animation) << "two bone var " << _enabledVar; if (enabled != _enabled) { AnimChain poseChain; poseChain.buildFromRelativePoses(_skeleton, _poses, _tipJointIndex); @@ -91,7 +92,7 @@ const AnimPoseVec& AnimTwoBoneIK::evaluate(const AnimVariantMap& animVars, const _enabled = enabled; // don't build chains or do IK if we are disabled & not interping. - if (_interpType == InterpType::None){// && !enabled) { + if (_interpType == InterpType::None && !enabled) { _poses = underPoses; return _poses; } @@ -122,6 +123,7 @@ const AnimPoseVec& AnimTwoBoneIK::evaluate(const AnimVariantMap& animVars, const // First look in the triggers then look in the animVars, so we can follow output joints underneath us in the anim graph AnimPose targetPose(tipPose); if (triggersOut.hasKey(endEffectorRotationVar)) { + qCDebug(animation) << " end effector variable " << endEffectorRotationVar << " is " << triggersOut.lookupRigToGeometry(endEffectorRotationVar, tipPose.rot()); targetPose.rot() = triggersOut.lookupRigToGeometry(endEffectorRotationVar, tipPose.rot()); } else if (animVars.hasKey(endEffectorRotationVar)) { targetPose.rot() = animVars.lookupRigToGeometry(endEffectorRotationVar, tipPose.rot()); diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index e1db2fef8f..a34af09b27 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -1541,7 +1541,7 @@ void Rig::updateHands2(bool leftHandEnabled, bool rightHandEnabled, bool headEna int handJointIndex = _animSkeleton->nameToJointIndex("LeftHand"); int elbowJointIndex = _animSkeleton->nameToJointIndex("LeftForeArm"); int shoulderJointIndex = _animSkeleton->nameToJointIndex("LeftArm"); - int oppositeArmJointIndex = _animSkeleton->nameToJointIndex("LeftArm"); + int oppositeArmJointIndex = _animSkeleton->nameToJointIndex("RightArm"); glm::vec3 poleVector; bool usePoleVector = calculateElbowPoleVector(handJointIndex, elbowJointIndex, shoulderJointIndex, oppositeArmJointIndex, poleVector); glm::vec3 sensorPoleVector = transformVectorFast(rigToSensorMatrix, poleVector); @@ -1580,7 +1580,7 @@ void Rig::updateHands2(bool leftHandEnabled, bool rightHandEnabled, bool headEna int handJointIndex = _animSkeleton->nameToJointIndex("RightHand"); int elbowJointIndex = _animSkeleton->nameToJointIndex("RightForeArm"); int shoulderJointIndex = _animSkeleton->nameToJointIndex("RightArm"); - int oppositeArmJointIndex = _animSkeleton->nameToJointIndex("RightArm"); + int oppositeArmJointIndex = _animSkeleton->nameToJointIndex("LeftArm"); glm::vec3 poleVector; bool usePoleVector = calculateElbowPoleVector(handJointIndex, elbowJointIndex, shoulderJointIndex, oppositeArmJointIndex, poleVector); glm::vec3 sensorPoleVector = transformVectorFast(rigToSensorMatrix, poleVector); @@ -1856,10 +1856,10 @@ void Rig::updateFromControllerParameters(const ControllerParameters& params, flo updateHead(_headEnabled, hipsEnabled, params.primaryControllerPoses[PrimaryControllerType_Head]); - updateHands(leftHandEnabled, rightHandEnabled, hipsEnabled, hipsEstimated, leftArmEnabled, rightArmEnabled, _headEnabled, dt, - params.primaryControllerPoses[PrimaryControllerType_LeftHand], params.primaryControllerPoses[PrimaryControllerType_RightHand], - params.hipsShapeInfo, params.spineShapeInfo, params.spine1ShapeInfo, params.spine2ShapeInfo, - params.rigToSensorMatrix, sensorToRigMatrix); + //updateHands(leftHandEnabled, rightHandEnabled, hipsEnabled, hipsEstimated, leftArmEnabled, rightArmEnabled, _headEnabled, dt, + // params.primaryControllerPoses[PrimaryControllerType_LeftHand], params.primaryControllerPoses[PrimaryControllerType_RightHand], + // params.hipsShapeInfo, params.spineShapeInfo, params.spine1ShapeInfo, params.spine2ShapeInfo, + // params.rigToSensorMatrix, sensorToRigMatrix); updateHands2(leftHandEnabled, rightHandEnabled, _headEnabled, params.primaryControllerPoses[PrimaryControllerType_LeftHand], params.primaryControllerPoses[PrimaryControllerType_RightHand], @@ -1940,7 +1940,7 @@ void Rig::updateFromControllerParameters(const ControllerParameters& params, flo std::shared_ptr ikNode = getAnimInverseKinematicsNode(); for (int i = 0; i < (int)NumSecondaryControllerTypes; i++) { int index = indexOfJoint(secondaryControllerJointNames[i]); - if (index >= 0) { + if ((index >= 0) && (ikNode)) { if (params.secondaryControllerFlags[i] & (uint8_t)ControllerFlags::Enabled) { ikNode->setSecondaryTargetInRigFrame(index, params.secondaryControllerPoses[i]); } else { From dbd03e2eb411b297587fde8ea9d44ee5cc81aff3 Mon Sep 17 00:00:00 2001 From: amantley Date: Tue, 22 Jan 2019 11:53:18 -0800 Subject: [PATCH 012/112] got the spline arms and legs working without any inverse kinematic node in the json, using _withIKnode.json --- .../avatar/avatar-animation_withIKNode.json | 2240 +++++++++++++++++ .../animation/src/AnimInverseKinematics.cpp | 5 +- libraries/animation/src/AnimSplineIK.cpp | 15 + libraries/animation/src/AnimSplineIK.h | 2 + 4 files changed, 2260 insertions(+), 2 deletions(-) create mode 100644 interface/resources/avatar/avatar-animation_withIKNode.json diff --git a/interface/resources/avatar/avatar-animation_withIKNode.json b/interface/resources/avatar/avatar-animation_withIKNode.json new file mode 100644 index 0000000000..8a66ed21b3 --- /dev/null +++ b/interface/resources/avatar/avatar-animation_withIKNode.json @@ -0,0 +1,2240 @@ +{ + "version": "1.1", + "root": { + "id": "userAnimStateMachine", + "type": "stateMachine", + "data": { + "currentState": "userAnimNone", + "states": [ + { + "id": "userAnimNone", + "interpTarget": 6, + "interpDuration": 6, + "transitions": [ + { + "var": "userAnimA", + "state": "userAnimA" + }, + { + "var": "userAnimB", + "state": "userAnimB" + } + ] + }, + { + "id": "userAnimA", + "interpTarget": 6, + "interpDuration": 6, + "transitions": [ + { + "var": "userAnimNone", + "state": "userAnimNone" + }, + { + "var": "userAnimB", + "state": "userAnimB" + } + ] + }, + { + "id": "userAnimB", + "interpTarget": 6, + "interpDuration": 6, + "transitions": [ + { + "var": "userAnimNone", + "state": "userAnimNone" + }, + { + "var": "userAnimA", + "state": "userAnimA" + } + ] + } + ] + }, + "children": [ + { + "id": "userAnimNone", + "type": "poleVectorConstraint", + "data": { + "enabled": false, + "referenceVector": [ 0, 0, 1 ], + "baseJointName": "RightUpLeg", + "midJointName": "RightLeg", + "tipJointName": "RightFoot", + "enabledVar": "rightFootPoleVectorEnabled", + "poleVectorVar": "rightFootPoleVector" + }, + "children": [ + { + "id": "rightFootIK", + "type": "twoBoneIK", + "data": { + "alpha": 1.0, + "enabled": false, + "interpDuration": 15, + "baseJointName": "RightUpLeg", + "midJointName": "RightLeg", + "tipJointName": "RightFoot", + "midHingeAxis": [ -1, 0, 0 ], + "alphaVar": "rightFootIKAlpha", + "enabledVar": "rightFootIKEnabled", + "endEffectorRotationVarVar": "rightFootIKRotationVar", + "endEffectorPositionVarVar": "rightFootIKPositionVar" + }, + "children": [ + { + "id": "leftFootPoleVector", + "type": "poleVectorConstraint", + "data": { + "enabled": false, + "referenceVector": [ 0, 0, 1 ], + "baseJointName": "LeftUpLeg", + "midJointName": "LeftLeg", + "tipJointName": "LeftFoot", + "enabledVar": "leftFootPoleVectorEnabled", + "poleVectorVar": "leftFootPoleVector" + }, + "children": [ + { + "id": "leftFootIK", + "type": "twoBoneIK", + "data": { + "alpha": 1.0, + "enabled": false, + "interpDuration": 15, + "baseJointName": "LeftUpLeg", + "midJointName": "LeftLeg", + "tipJointName": "LeftFoot", + "midHingeAxis": [ -1, 0, 0 ], + "alphaVar": "leftFootIKAlpha", + "enabledVar": "leftFootIKEnabled", + "endEffectorRotationVarVar": "leftFootIKRotationVar", + "endEffectorPositionVarVar": "leftFootIKPositionVar" + }, + "children": [ + { + "id": "rightHandPoleVector", + "type": "poleVectorConstraint", + "data": { + "enabled": false, + "referenceVector": [ 0, 0, 1 ], + "baseJointName": "RightArm", + "midJointName": "RightForeArm", + "tipJointName": "RightHand", + "enabledVar": "rightHandPoleVectorEnabled", + "poleVectorVar": "rightHandPoleVector" + }, + "children": [ + { + "id": "rightHandIK", + "type": "twoBoneIK", + "data": { + "alpha": 1.0, + "enabled": false, + "interpDuration": 15, + "baseJointName": "RightArm", + "midJointName": "RightForeArm", + "tipJointName": "RightHand", + "midHingeAxis": [ 0, 0, -1 ], + "alphaVar": "rightHandIKAlpha", + "enabledVar": "rightHandIKEnabled", + "endEffectorRotationVarVar": "rightHandIKRotationVar", + "endEffectorPositionVarVar": "rightHandIKPositionVar" + }, + "children": [ + { + "id": "leftHandPoleVector", + "type": "poleVectorConstraint", + "data": { + "enabled": false, + "referenceVector": [ 0, 0, 1 ], + "baseJointName": "LeftArm", + "midJointName": "LeftForeArm", + "tipJointName": "LeftHand", + "enabledVar": "leftHandPoleVectorEnabled", + "poleVectorVar": "leftHandPoleVector" + }, + "children": [ + { + "id": "leftHandIK", + "type": "twoBoneIK", + "data": { + "alpha": 1.0, + "enabled": false, + "interpDuration": 15, + "baseJointName": "LeftArm", + "midJointName": "LeftForeArm", + "tipJointName": "LeftHand", + "midHingeAxis": [ 0, 0, 1 ], + "alphaVar": "leftHandIKAlpha", + "enabledVar": "leftHandIKEnabled", + "endEffectorRotationVarVar": "leftHandIKRotationVar", + "endEffectorPositionVarVar": "leftHandIKPositionVar" + }, + "children": [ + { + "id": "userSplineIK", + "type": "splineIK", + "data": { + "alpha": 1.0, + "enabled": false, + "interpDuration": 15, + "baseJointName": "Hips", + "tipJointName": "Head", + "alphaVar": "splineIKAlpha", + "enabledVar": "splineIKEnabled", + "endEffectorRotationVarVar": "splineIKRotationVar", + "endEffectorPositionVarVar": "splineIKPositionVar" + }, + "children": [ + { + "id": "ikOverlay", + "type": "overlay", + "data": { + "alpha": 0.0, + "alphaVar": "ikOverlayAlpha", + "boneSet": "fullBody" + }, + "children": [ + { + "id": "defaultPose", + "type": "defaultPose", + "data": { + }, + "children": [] + }, + { + "id": "defaultPoseOverlay", + "type": "overlay", + "data": { + "alpha": 0.0, + "alphaVar": "defaultPoseOverlayAlpha", + "boneSet": "fullBody", + "boneSetVar": "defaultPoseOverlayBoneSet" + }, + "children": [ + { + "id": "defaultPose", + "type": "defaultPose", + "data": { + }, + "children": [] + }, + { + "id": "rightHandOverlay", + "type": "overlay", + "data": { + "alpha": 0.0, + "boneSet": "rightHand", + "alphaVar": "rightHandOverlayAlpha" + }, + "children": [ + { + "id": "rightHandStateMachine", + "type": "stateMachine", + "data": { + "currentState": "rightHandGrasp", + "states": [ + { + "id": "rightHandGrasp", + "interpTarget": 3, + "interpDuration": 3, + "transitions": [ + { + "var": "isRightIndexPoint", + "state": "rightIndexPoint" + }, + { + "var": "isRightThumbRaise", + "state": "rightThumbRaise" + }, + { + "var": "isRightIndexPointAndThumbRaise", + "state": "rightIndexPointAndThumbRaise" + } + ] + }, + { + "id": "rightIndexPoint", + "interpTarget": 15, + "interpDuration": 3, + "transitions": [ + { + "var": "isRightHandGrasp", + "state": "rightHandGrasp" + }, + { + "var": "isRightThumbRaise", + "state": "rightThumbRaise" + }, + { + "var": "isRightIndexPointAndThumbRaise", + "state": "rightIndexPointAndThumbRaise" + } + ] + }, + { + "id": "rightThumbRaise", + "interpTarget": 15, + "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" + } + ] + } + ] + }, + "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", + "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": "mainStateMachine", + "type": "stateMachine", + "data": { + "outputJoints": [ "LeftFoot", "RightFoot" ], + "currentState": "idle", + "states": [ + { + "id": "idle", + "interpTarget": 20, + "interpDuration": 8, + "interpType": "snapshotPrev", + "transitions": [ + { + "var": "isMovingForward", + "state": "WALKFWD" + }, + { + "var": "isMovingBackward", + "state": "WALKBWD" + }, + { + "var": "isMovingRight", + "state": "STRAFERIGHT" + }, + { + "var": "isMovingLeft", + "state": "STRAFELEFT" + }, + { + "var": "isTurningRight", + "state": "turnRight" + }, + { + "var": "isTurningLeft", + "state": "turnLeft" + }, + { + "var": "isFlying", + "state": "fly" + }, + { + "var": "isTakeoffStand", + "state": "takeoffStand" + }, + { + "var": "isTakeoffRun", + "state": "TAKEOFFRUN" + }, + { + "var": "isInAirStand", + "state": "inAirStand" + }, + { + "var": "isInAirRun", + "state": "INAIRRUN" + }, + { + "var": "isMovingRightHmd", + "state": "strafeRightHmd" + }, + { + "var": "isMovingLeftHmd", + "state": "strafeLeftHmd" + } + ] + }, + { + "id": "idleToWalkFwd", + "interpTarget": 12, + "interpDuration": 8, + "transitions": [ + { + "var": "idleToWalkFwdOnDone", + "state": "WALKFWD" + }, + { + "var": "isNotMoving", + "state": "idle" + }, + { + "var": "isMovingBackward", + "state": "WALKBWD" + }, + { + "var": "isMovingRight", + "state": "STRAFERIGHT" + }, + { + "var": "isMovingLeft", + "state": "STRAFELEFT" + }, + { + "var": "isTurningRight", + "state": "turnRight" + }, + { + "var": "isTurningLeft", + "state": "turnLeft" + }, + { + "var": "isFlying", + "state": "fly" + }, + { + "var": "isTakeoffStand", + "state": "takeoffStand" + }, + { + "var": "isTakeoffRun", + "state": "TAKEOFFRUN" + }, + { + "var": "isInAirStand", + "state": "inAirStand" + }, + { + "var": "isInAirRun", + "state": "INAIRRUN" + }, + { + "var": "isMovingRightHmd", + "state": "strafeRightHmd" + }, + { + "var": "isMovingLeftHmd", + "state": "strafeLeftHmd" + } + ] + }, + { + "id": "idleSettle", + "interpTarget": 15, + "interpDuration": 8, + "interpType": "snapshotPrev", + "transitions": [ + { + "var": "idleSettleOnDone", + "state": "idle" + }, + { + "var": "isMovingForward", + "state": "WALKFWD" + }, + { + "var": "isMovingBackward", + "state": "WALKBWD" + }, + { + "var": "isMovingRight", + "state": "STRAFERIGHT" + }, + { + "var": "isMovingLeft", + "state": "STRAFELEFT" + }, + { + "var": "isMovingRightHmd", + "state": "strafeRightHmd" + }, + { + "var": "isMovingLeftHmd", + "state": "strafeLeftHmd" + }, + { + "var": "isTurningRight", + "state": "turnRight" + }, + { + "var": "isTurningLeft", + "state": "turnLeft" + }, + { + "var": "isFlying", + "state": "fly" + }, + { + "var": "isTakeoffStand", + "state": "takeoffStand" + }, + { + "var": "isTakeoffRun", + "state": "TAKEOFFRUN" + }, + { + "var": "isInAirStand", + "state": "inAirStand" + }, + { + "var": "isInAirRun", + "state": "INAIRRUN" + } + ] + }, + { + "id": "WALKFWD", + "interpTarget": 35, + "interpDuration": 10, + "interpType": "snapshotPrev", + "transitions": [ + { + "var": "isNotMoving", + "state": "idleSettle" + }, + { + "var": "isMovingBackward", + "state": "WALKBWD" + }, + { + "var": "isMovingRight", + "state": "STRAFERIGHT" + }, + { + "var": "isMovingLeft", + "state": "STRAFELEFT" + }, + { + "var": "isTurningRight", + "state": "turnRight" + }, + { + "var": "isTurningLeft", + "state": "turnLeft" + }, + { + "var": "isFlying", + "state": "fly" + }, + { + "var": "isTakeoffStand", + "state": "takeoffStand" + }, + { + "var": "isTakeoffRun", + "state": "TAKEOFFRUN" + }, + { + "var": "isInAirStand", + "state": "inAirStand" + }, + { + "var": "isInAirRun", + "state": "INAIRRUN" + }, + { + "var": "isMovingRightHmd", + "state": "strafeRightHmd" + }, + { + "var": "isMovingLeftHmd", + "state": "strafeLeftHmd" + } + ] + }, + { + "id": "WALKBWD", + "interpTarget": 35, + "interpDuration": 10, + "interpType": "snapshotPrev", + "transitions": [ + { + "var": "isNotMoving", + "state": "idleSettle" + }, + { + "var": "isMovingForward", + "state": "WALKFWD" + }, + { + "var": "isMovingRight", + "state": "STRAFERIGHT" + }, + { + "var": "isMovingLeft", + "state": "STRAFELEFT" + }, + { + "var": "isTurningRight", + "state": "turnRight" + }, + { + "var": "isTurningLeft", + "state": "turnLeft" + }, + { + "var": "isFlying", + "state": "fly" + }, + { + "var": "isTakeoffStand", + "state": "takeoffStand" + }, + { + "var": "isTakeoffRun", + "state": "TAKEOFFRUN" + }, + { + "var": "isInAirStand", + "state": "inAirStand" + }, + { + "var": "isInAirRun", + "state": "INAIRRUN" + }, + { + "var": "isMovingRightHmd", + "state": "strafeRightHmd" + }, + { + "var": "isMovingLeftHmd", + "state": "strafeLeftHmd" + } + ] + }, + { + "id": "STRAFERIGHT", + "interpTarget": 25, + "interpDuration": 8, + "interpType": "snapshotPrev", + "transitions": [ + { + "var": "isNotMoving", + "state": "idleSettle" + }, + { + "var": "isMovingForward", + "state": "WALKFWD" + }, + { + "var": "isMovingBackward", + "state": "WALKBWD" + }, + { + "var": "isMovingLeft", + "state": "STRAFELEFT" + }, + { + "var": "isTurningRight", + "state": "turnRight" + }, + { + "var": "isTurningLeft", + "state": "turnLeft" + }, + { + "var": "isFlying", + "state": "fly" + }, + { + "var": "isTakeoffStand", + "state": "takeoffStand" + }, + { + "var": "isTakeoffRun", + "state": "TAKEOFFRUN" + }, + { + "var": "isInAirStand", + "state": "inAirStand" + }, + { + "var": "isInAirRun", + "state": "INAIRRUN" + }, + { + "var": "isMovingRightHmd", + "state": "strafeRightHmd" + }, + { + "var": "isMovingLeftHmd", + "state": "strafeLeftHmd" + } + ] + }, + { + "id": "STRAFELEFT", + "interpTarget": 25, + "interpDuration": 8, + "interpType": "snapshotPrev", + "transitions": [ + { + "var": "isNotMoving", + "state": "idleSettle" + }, + { + "var": "isMovingForward", + "state": "WALKFWD" + }, + { + "var": "isMovingBackward", + "state": "WALKBWD" + }, + { + "var": "isMovingRight", + "state": "STRAFERIGHT" + }, + { + "var": "isTurningRight", + "state": "turnRight" + }, + { + "var": "isTurningLeft", + "state": "turnLeft" + }, + { + "var": "isFlying", + "state": "fly" + }, + { + "var": "isTakeoffStand", + "state": "takeoffStand" + }, + { + "var": "isTakeoffRun", + "state": "TAKEOFFRUN" + }, + { + "var": "isInAirStand", + "state": "inAirStand" + }, + { + "var": "isInAirRun", + "state": "INAIRRUN" + }, + { + "var": "isMovingRightHmd", + "state": "strafeRightHmd" + }, + { + "var": "isMovingLeftHmd", + "state": "strafeLeftHmd" + } + ] + }, + { + "id": "turnRight", + "interpTarget": 6, + "interpDuration": 8, + "transitions": [ + { + "var": "isNotTurning", + "state": "idle" + }, + { + "var": "isMovingForward", + "state": "WALKFWD" + }, + { + "var": "isMovingBackward", + "state": "WALKBWD" + }, + { + "var": "isMovingRight", + "state": "STRAFERIGHT" + }, + { + "var": "isMovingLeft", + "state": "STRAFELEFT" + }, + { + "var": "isTurningLeft", + "state": "turnLeft" + }, + { + "var": "isFlying", + "state": "fly" + }, + { + "var": "isTakeoffStand", + "state": "takeoffStand" + }, + { + "var": "isTakeoffRun", + "state": "TAKEOFFRUN" + }, + { + "var": "isInAirStand", + "state": "inAirStand" + }, + { + "var": "isInAirRun", + "state": "INAIRRUN" + }, + { + "var": "isMovingRightHmd", + "state": "strafeRightHmd" + }, + { + "var": "isMovingLeftHmd", + "state": "strafeLeftHmd" + } + ] + }, + { + "id": "turnLeft", + "interpTarget": 6, + "interpDuration": 8, + "transitions": [ + { + "var": "isNotTurning", + "state": "idle" + }, + { + "var": "isMovingForward", + "state": "WALKFWD" + }, + { + "var": "isMovingBackward", + "state": "WALKBWD" + }, + { + "var": "isMovingRight", + "state": "STRAFERIGHT" + }, + { + "var": "isMovingLeft", + "state": "STRAFELEFT" + }, + { + "var": "isTurningRight", + "state": "turnRight" + }, + { + "var": "isFlying", + "state": "fly" + }, + { + "var": "isTakeoffStand", + "state": "takeoffStand" + }, + { + "var": "isTakeoffRun", + "state": "TAKEOFFRUN" + }, + { + "var": "isInAirStand", + "state": "inAirStand" + }, + { + "var": "isInAirRun", + "state": "INAIRRUN" + }, + { + "var": "isMovingRightHmd", + "state": "strafeRightHmd" + }, + { + "var": "isMovingLeftHmd", + "state": "strafeLeftHmd" + } + ] + }, + { + "id": "strafeRightHmd", + "interpTarget": 5, + "interpDuration": 8, + "interpType": "snapshotPrev", + "transitions": [ + { + "var": "isNotMoving", + "state": "idleSettle" + }, + { + "var": "isMovingForward", + "state": "WALKFWD" + }, + { + "var": "isMovingBackward", + "state": "WALKBWD" + }, + { + "var": "isMovingLeftHmd", + "state": "strafeLeftHmd" + }, + { + "var": "isMovingRight", + "state": "STRAFERIGHT" + }, + { + "var": "isMovingLeft", + "state": "STRAFELEFT" + }, + { + "var": "isTurningRight", + "state": "turnRight" + }, + { + "var": "isTurningLeft", + "state": "turnLeft" + }, + { + "var": "isFlying", + "state": "fly" + }, + { + "var": "isTakeoffStand", + "state": "takeoffStand" + }, + { + "var": "isTakeoffRun", + "state": "TAKEOFFRUN" + }, + { + "var": "isInAirStand", + "state": "inAirStand" + }, + { + "var": "isInAirRun", + "state": "INAIRRUN" + } + ] + }, + { + "id": "strafeLeftHmd", + "interpTarget": 5, + "interpDuration": 8, + "interpType": "snapshotPrev", + "transitions": [ + { + "var": "isNotMoving", + "state": "idleSettle" + }, + { + "var": "isMovingForward", + "state": "WALKFWD" + }, + { + "var": "isMovingBackward", + "state": "WALKBWD" + }, + { + "var": "isMovingRightHmd", + "state": "strafeRightHmd" + }, + { + "var": "isMovingRight", + "state": "STRAFERIGHT" + }, + { + "var": "isMovingLeft", + "state": "STRAFELEFT" + }, + { + "var": "isTurningRight", + "state": "turnRight" + }, + { + "var": "isTurningLeft", + "state": "turnLeft" + }, + { + "var": "isFlying", + "state": "fly" + }, + { + "var": "isTakeoffStand", + "state": "takeoffStand" + }, + { + "var": "isTakeoffRun", + "state": "TAKEOFFRUN" + }, + { + "var": "isInAirStand", + "state": "inAirStand" + }, + { + "var": "isInAirRun", + "state": "INAIRRUN" + } + ] + }, + { + "id": "fly", + "interpTarget": 6, + "interpDuration": 6, + "transitions": [ + { + "var": "isNotFlying", + "state": "idleSettle" + } + ] + }, + { + "id": "takeoffStand", + "interpTarget": 2, + "interpDuration": 2, + "transitions": [ + { + "var": "isNotTakeoff", + "state": "inAirStand" + } + ] + }, + { + "id": "TAKEOFFRUN", + "interpTarget": 2, + "interpDuration": 2, + "transitions": [ + { + "var": "isNotTakeoff", + "state": "INAIRRUN" + } + ] + }, + { + "id": "inAirStand", + "interpTarget": 3, + "interpDuration": 3, + "interpType": "snapshotPrev", + "transitions": [ + { + "var": "isNotInAir", + "state": "landStandImpact" + } + ] + }, + { + "id": "INAIRRUN", + "interpTarget": 3, + "interpDuration": 3, + "interpType": "snapshotPrev", + "transitions": [ + { + "var": "isNotInAir", + "state": "WALKFWD" + } + ] + }, + { + "id": "landStandImpact", + "interpTarget": 1, + "interpDuration": 1, + "transitions": [ + { + "var": "isFlying", + "state": "fly" + }, + { + "var": "isTakeoffStand", + "state": "takeoffStand" + }, + { + "var": "isTakeoffRun", + "state": "TAKEOFFRUN" + }, + { + "var": "landStandImpactOnDone", + "state": "landStand" + } + ] + }, + { + "id": "landStand", + "interpTarget": 1, + "interpDuration": 1, + "transitions": [ + { + "var": "isMovingForward", + "state": "WALKFWD" + }, + { + "var": "isMovingBackward", + "state": "WALKBWD" + }, + { + "var": "isMovingRight", + "state": "STRAFERIGHT" + }, + { + "var": "isMovingLeft", + "state": "STRAFELEFT" + }, + { + "var": "isTurningRight", + "state": "turnRight" + }, + { + "var": "isTurningLeft", + "state": "turnLeft" + }, + { + "var": "isFlying", + "state": "fly" + }, + { + "var": "isTakeoffStand", + "state": "takeoffStand" + }, + { + "var": "isTakeoffRun", + "state": "TAKEOFFRUN" + }, + { + "var": "isInAirStand", + "state": "inAirStand" + }, + { + "var": "isInAirRun", + "state": "INAIRRUN" + }, + { + "var": "landStandOnDone", + "state": "idle" + }, + { + "var": "isMovingRightHmd", + "state": "strafeRightHmd" + }, + { + "var": "isMovingLeftHmd", + "state": "strafeLeftHmd" + } + ] + }, + { + "id": "LANDRUN", + "interpTarget": 2, + "interpDuration": 2, + "transitions": [ + { + "var": "isFlying", + "state": "fly" + }, + { + "var": "isTakeoffStand", + "state": "takeoffStand" + }, + { + "var": "isTakeoffRun", + "state": "TAKEOFFRUN" + }, + { + "var": "landRunOnDone", + "state": "WALKFWD" + } + ] + } + ] + }, + "children": [ + { + "id": "idle", + "type": "stateMachine", + "data": { + "currentState": "idleStand", + "states": [ + { + "id": "idleStand", + "interpTarget": 6, + "interpDuration": 10, + "transitions": [ + { + "var": "isTalking", + "state": "idleTalk" + } + ] + }, + { + "id": "idleTalk", + "interpTarget": 6, + "interpDuration": 10, + "transitions": [ + { + "var": "notIsTalking", + "state": "idleStand" + } + ] + } + ] + }, + "children": [ + { + "id": "idleStand", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/idle.fbx", + "startFrame": 0.0, + "endFrame": 300.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "idleTalk", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/talk.fbx", + "startFrame": 0.0, + "endFrame": 800.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + } + ] + }, + { + "id": "WALKFWD", + "type": "blendLinearMove", + "data": { + "alpha": 0.0, + "desiredSpeed": 1.4, + "characteristicSpeeds": [ 0.5, 1.8, 2.3, 3.2, 4.5 ], + "alphaVar": "moveForwardAlpha", + "desiredSpeedVar": "moveForwardSpeed" + }, + "children": [ + { + "id": "walkFwdShort_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/walk_short_fwd.fbx", + "startFrame": 0.0, + "endFrame": 39.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "walkFwdNormal_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/walk_fwd.fbx", + "startFrame": 0.0, + "endFrame": 30.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "walkFwdFast_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/walk_fwd_fast.fbx", + "startFrame": 0.0, + "endFrame": 25.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "walkFwdJog_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jog_fwd.fbx", + "startFrame": 0.0, + "endFrame": 25.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "walkFwdRun_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/run_fwd.fbx", + "startFrame": 0.0, + "endFrame": 21.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + } + ] + }, + { + "id": "idleToWalkFwd", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/idle_to_walk.fbx", + "startFrame": 1.0, + "endFrame": 13.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] + }, + { + "id": "idleSettle", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/settle_to_idle.fbx", + "startFrame": 1.0, + "endFrame": 59.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] + }, + { + "id": "WALKBWD", + "type": "blendLinearMove", + "data": { + "alpha": 0.0, + "desiredSpeed": 1.4, + "characteristicSpeeds": [ 0.6, 1.6, 2.3, 3.1 ], + "alphaVar": "moveBackwardAlpha", + "desiredSpeedVar": "moveBackwardSpeed" + }, + "children": [ + { + "id": "walkBwdShort_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/walk_short_bwd.fbx", + "startFrame": 0.0, + "endFrame": 38.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "walkBwdFast_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/walk_bwd_fast.fbx", + "startFrame": 0.0, + "endFrame": 27.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "jogBwd_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jog_bwd.fbx", + "startFrame": 0.0, + "endFrame": 24.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "runBwd_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/run_bwd.fbx", + "startFrame": 0.0, + "endFrame": 16.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + } + ] + }, + { + "id": "turnLeft", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/turn_left.fbx", + "startFrame": 0.0, + "endFrame": 32.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "turnRight", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/turn_left.fbx", + "startFrame": 0.0, + "endFrame": 32.0, + "timeScale": 1.0, + "loopFlag": true, + "mirrorFlag": true + }, + "children": [] + }, + { + "id": "STRAFELEFT", + "type": "blendLinearMove", + "data": { + "alpha": 0.0, + "desiredSpeed": 1.4, + "characteristicSpeeds": [ 0.1, 0.5, 1.0, 2.6, 3.0 ], + "alphaVar": "moveLateralAlpha", + "desiredSpeedVar": "moveLateralSpeed" + }, + "children": [ + { + "id": "strafeLeftShortStep_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/side_step_short_left.fbx", + "startFrame": 0.0, + "endFrame": 29.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "strafeLeftStep_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/side_step_left.fbx", + "startFrame": 0.0, + "endFrame": 20.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "strafeLeftWalk_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/walk_left.fbx", + "startFrame": 0.0, + "endFrame": 35.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "strafeLeftWalkFast_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/walk_left_fast.fbx", + "startFrame": 0.0, + "endFrame": 21.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "strafeLeftJog_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jog_left.fbx", + "startFrame": 0.0, + "endFrame": 24.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + } + ] + }, + { + "id": "STRAFERIGHT", + "type": "blendLinearMove", + "data": { + "alpha": 0.0, + "desiredSpeed": 1.4, + "characteristicSpeeds": [ 0.1, 0.5, 1.0, 2.6, 3.0 ], + "alphaVar": "moveLateralAlpha", + "desiredSpeedVar": "moveLateralSpeed" + }, + "children": [ + { + "id": "strafeRightShortStep_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/side_step_short_left.fbx", + "startFrame": 0.0, + "endFrame": 29.0, + "timeScale": 1.0, + "loopFlag": true, + "mirrorFlag": true + }, + "children": [] + }, + { + "id": "strafeRightStep_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/side_step_left.fbx", + "startFrame": 0.0, + "endFrame": 20.0, + "timeScale": 1.0, + "loopFlag": true, + "mirrorFlag": true + }, + "children": [] + }, + { + "id": "strafeRightWalk_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/walk_left.fbx", + "startFrame": 0.0, + "endFrame": 35.0, + "timeScale": 1.0, + "loopFlag": true, + "mirrorFlag": true + }, + "children": [] + }, + { + "id": "strafeRightFast_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/walk_left_fast.fbx", + "startFrame": 0.0, + "endFrame": 21.0, + "timeScale": 1.0, + "loopFlag": true, + "mirrorFlag": true + }, + "children": [] + }, + { + "id": "strafeRightJog_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jog_left.fbx", + "startFrame": 0.0, + "endFrame": 24.0, + "timeScale": 1.0, + "loopFlag": true, + "mirrorFlag": true + }, + "children": [] + } + ] + }, + { + "id": "strafeLeftHmd", + "type": "blendLinearMove", + "data": { + "alpha": 0.0, + "desiredSpeed": 1.4, + "characteristicSpeeds": [ 0, 0.5, 2.5 ], + "alphaVar": "moveLateralAlpha", + "desiredSpeedVar": "moveLateralSpeed" + }, + "children": [ + { + "id": "stepLeftShort_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/side_step_short_left.fbx", + "startFrame": 0.0, + "endFrame": 29.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "stepLeft_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/side_step_left.fbx", + "startFrame": 0.0, + "endFrame": 20.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "strafeLeftAnim_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/side_step_left_fast.fbx", + "startFrame": 0.0, + "endFrame": 16.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + } + ] + }, + { + "id": "strafeRightHmd", + "type": "blendLinearMove", + "data": { + "alpha": 0.0, + "desiredSpeed": 1.4, + "characteristicSpeeds": [ 0, 0.5, 2.5 ], + "alphaVar": "moveLateralAlpha", + "desiredSpeedVar": "moveLateralSpeed" + }, + "children": [ + { + "id": "stepRightShort_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/side_step_short_left.fbx", + "startFrame": 0.0, + "endFrame": 29.0, + "timeScale": 1.0, + "loopFlag": true, + "mirrorFlag": true + }, + "children": [] + }, + { + "id": "stepRight_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/side_step_left.fbx", + "startFrame": 0.0, + "endFrame": 20.0, + "timeScale": 1.0, + "loopFlag": true, + "mirrorFlag": true + }, + "children": [] + }, + { + "id": "strafeRightAnim_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/side_step_left_fast.fbx", + "startFrame": 0.0, + "endFrame": 16.0, + "timeScale": 1.0, + "loopFlag": true, + "mirrorFlag": true + }, + "children": [] + } + ] + }, + { + "id": "fly", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/fly.fbx", + "startFrame": 1.0, + "endFrame": 80.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "takeoffStand", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jump_standing_launch.fbx", + "startFrame": 2.0, + "endFrame": 16.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] + }, + { + "id": "TAKEOFFRUN", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jump_running_launch_land.fbx", + "startFrame": 4.0, + "endFrame": 15.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] + }, + { + "id": "inAirStand", + "type": "blendLinear", + "data": { + "alpha": 0.0, + "alphaVar": "inAirAlpha" + }, + "children": [ + { + "id": "inAirStandPreApex", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jump_standing_apex.fbx", + "startFrame": 0.0, + "endFrame": 0.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] + }, + { + "id": "inAirStandApex", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jump_standing_apex.fbx", + "startFrame": 1.0, + "endFrame": 1.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] + }, + { + "id": "inAirStandPostApex", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jump_standing_apex.fbx", + "startFrame": 2.0, + "endFrame": 2.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] + } + ] + }, + { + "id": "INAIRRUN", + "type": "blendLinear", + "data": { + "alpha": 0.0, + "alphaVar": "inAirAlpha" + }, + "children": [ + { + "id": "inAirRunPreApex", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jump_running_launch_land.fbx", + "startFrame": 16.0, + "endFrame": 16.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] + }, + { + "id": "inAirRunApex", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jump_running_launch_land.fbx", + "startFrame": 22.0, + "endFrame": 22.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] + }, + { + "id": "inAirRunPostApex", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jump_running_launch_land.fbx", + "startFrame": 33.0, + "endFrame": 33.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] + } + ] + }, + { + "id": "landStandImpact", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jump_standing_land_settle.fbx", + "startFrame": 1.0, + "endFrame": 6.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] + }, + { + "id": "landStand", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jump_standing_land_settle.fbx", + "startFrame": 6.0, + "endFrame": 68.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] + }, + { + "id": "LANDRUN", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jump_running_launch_land.fbx", + "startFrame": 29.0, + "endFrame": 40.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + }, + { + "id": "userAnimA", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/idle.fbx", + "startFrame": 0.0, + "endFrame": 90.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "userAnimB", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/idle.fbx", + "startFrame": 0.0, + "endFrame": 90.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + } + ] + } +} diff --git a/libraries/animation/src/AnimInverseKinematics.cpp b/libraries/animation/src/AnimInverseKinematics.cpp index 8d2ba0fd78..7a29ff4001 100644 --- a/libraries/animation/src/AnimInverseKinematics.cpp +++ b/libraries/animation/src/AnimInverseKinematics.cpp @@ -886,7 +886,8 @@ const AnimPoseVec& AnimInverseKinematics::overlay(const AnimVariantMap& animVars if (dt > MAX_OVERLAY_DT) { dt = MAX_OVERLAY_DT; } - + loadPoses(underPoses); + /* if (_relativePoses.size() != underPoses.size()) { loadPoses(underPoses); } else { @@ -1054,7 +1055,7 @@ const AnimPoseVec& AnimInverseKinematics::overlay(const AnimVariantMap& animVars } processOutputJoints(triggersOut); - + */ return _relativePoses; } diff --git a/libraries/animation/src/AnimSplineIK.cpp b/libraries/animation/src/AnimSplineIK.cpp index 23bf8b2800..847d512a51 100644 --- a/libraries/animation/src/AnimSplineIK.cpp +++ b/libraries/animation/src/AnimSplineIK.cpp @@ -40,6 +40,12 @@ AnimSplineIK::~AnimSplineIK() { } +//virtual +const AnimPoseVec& AnimSplineIK::overlay(const AnimVariantMap& animVars, const AnimContext& context, float dt, AnimVariantMap& triggersOut, const AnimPoseVec& underPoses) { + loadPoses(underPoses); + return _poses; +} + const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const AnimContext& context, float dt, AnimVariantMap& triggersOut) { assert(_children.size() == 1); if (_children.size() != 1) { @@ -444,4 +450,13 @@ void AnimSplineIK::computeAndCacheSplineJointInfosForIKTarget(const AnimContext& } _splineJointInfoMap[target.getIndex()] = splineJointInfoVec; +} + +void AnimSplineIK ::loadPoses(const AnimPoseVec& poses) { + assert(_skeleton && ((poses.size() == 0) || (_skeleton->getNumJoints() == (int)poses.size()))); + if (_skeleton->getNumJoints() == (int)poses.size()) { + _poses = poses; + } else { + _poses.clear(); + } } \ No newline at end of file diff --git a/libraries/animation/src/AnimSplineIK.h b/libraries/animation/src/AnimSplineIK.h index d303f81053..12f43fa680 100644 --- a/libraries/animation/src/AnimSplineIK.h +++ b/libraries/animation/src/AnimSplineIK.h @@ -25,6 +25,7 @@ public: virtual ~AnimSplineIK() override; virtual const AnimPoseVec& evaluate(const AnimVariantMap& animVars, const AnimContext& context, float dt, AnimVariantMap& triggersOut) override; + virtual const AnimPoseVec& overlay(const AnimVariantMap& animVars, const AnimContext& context, float dt, AnimVariantMap& triggersOut, const AnimPoseVec& underPoses) override; protected: @@ -36,6 +37,7 @@ protected: }; void computeAbsolutePoses(AnimPoseVec& absolutePoses) const; + void loadPoses(const AnimPoseVec& poses); // for AnimDebugDraw rendering virtual const AnimPoseVec& getPosesInternal() const override; From cdd03646c2ab95b5de2af30720a3735ca5ba93c1 Mon Sep 17 00:00:00 2001 From: amantley Date: Wed, 23 Jan 2019 17:22:13 -0800 Subject: [PATCH 013/112] latest spline code with ik node removed started cleanup --- .../resources/avatar/avatar-animation.json | 3086 +++++++---------- .../avatar/avatar-animation_withIKNode.json | 4 +- .../animation/src/AnimInverseKinematics.cpp | 11 +- libraries/animation/src/AnimSplineIK.cpp | 158 +- libraries/animation/src/Rig.cpp | 19 +- 5 files changed, 1321 insertions(+), 1957 deletions(-) diff --git a/interface/resources/avatar/avatar-animation.json b/interface/resources/avatar/avatar-animation.json index f68d7e61d4..50fe5019f9 100644 --- a/interface/resources/avatar/avatar-animation.json +++ b/interface/resources/avatar/avatar-animation.json @@ -38,256 +38,419 @@ "children": [ { "id": "userAnimNone", - "type": "splineIK", + "type": "poleVectorConstraint", "data": { - "alpha": 1.0, "enabled": false, - "interpDuration": 15, - "baseJointName": "Hips", - "tipJointName": "Head", - "alphaVar": "splineIKAlpha", - "enabledVar": "splineIKEnabled", - "endEffectorRotationVarVar": "splineIKRotationVar", - "endEffectorPositionVarVar": "splineIKPositionVar" + "referenceVector": [0, 0, 1], + "baseJointName": "RightUpLeg", + "midJointName": "RightLeg", + "tipJointName": "RightFoot", + "enabledVar": "rightFootPoleVectorEnabled", + "poleVectorVar": "rightFootPoleVector" }, "children": [ { - "id": "rightFootPoleVector", - "type": "poleVectorConstraint", + "id": "rightFootIK", + "type": "twoBoneIK", "data": { + "alpha": 1.0, "enabled": false, - "referenceVector": [ 0, 0, 1 ], + "interpDuration": 15, "baseJointName": "RightUpLeg", "midJointName": "RightLeg", "tipJointName": "RightFoot", - "enabledVar": "rightFootPoleVectorEnabled", - "poleVectorVar": "rightFootPoleVector" + "midHingeAxis": [-1, 0, 0], + "alphaVar": "rightFootIKAlpha", + "enabledVar": "rightFootIKEnabled", + "endEffectorRotationVarVar": "rightFootIKRotationVar", + "endEffectorPositionVarVar": "rightFootIKPositionVar" }, "children": [ { - "id": "rightFootIK", - "type": "twoBoneIK", + "id": "leftFootPoleVector", + "type": "poleVectorConstraint", "data": { - "alpha": 1.0, "enabled": false, - "interpDuration": 15, - "baseJointName": "RightUpLeg", - "midJointName": "RightLeg", - "tipJointName": "RightFoot", - "midHingeAxis": [ -1, 0, 0 ], - "alphaVar": "rightFootIKAlpha", - "enabledVar": "rightFootIKEnabled", - "endEffectorRotationVarVar": "rightFootIKRotationVar", - "endEffectorPositionVarVar": "rightFootIKPositionVar" + "referenceVector": [0, 0, 1], + "baseJointName": "LeftUpLeg", + "midJointName": "LeftLeg", + "tipJointName": "LeftFoot", + "enabledVar": "leftFootPoleVectorEnabled", + "poleVectorVar": "leftFootPoleVector" }, "children": [ { - "id": "leftFootPoleVector", - "type": "poleVectorConstraint", + "id": "leftFootIK", + "type": "twoBoneIK", "data": { + "alpha": 1.0, "enabled": false, - "referenceVector": [ 0, 0, 1 ], + "interpDuration": 15, "baseJointName": "LeftUpLeg", "midJointName": "LeftLeg", "tipJointName": "LeftFoot", - "enabledVar": "leftFootPoleVectorEnabled", - "poleVectorVar": "leftFootPoleVector" + "midHingeAxis": [-1, 0, 0], + "alphaVar": "leftFootIKAlpha", + "enabledVar": "leftFootIKEnabled", + "endEffectorRotationVarVar": "leftFootIKRotationVar", + "endEffectorPositionVarVar": "leftFootIKPositionVar" }, "children": [ { - "id": "leftFootIK", - "type": "twoBoneIK", + "id": "ikOverlay", + "type": "overlay", "data": { "alpha": 1.0, - "enabled": false, - "interpDuration": 15, - "baseJointName": "LeftUpLeg", - "midJointName": "LeftLeg", - "tipJointName": "LeftFoot", - "midHingeAxis": [ -1, 0, 0 ], - "alphaVar": "leftFootIKAlpha", - "enabledVar": "leftFootIKEnabled", - "endEffectorRotationVarVar": "leftFootIKRotationVar", - "endEffectorPositionVarVar": "leftFootIKPositionVar" + "alphaVar": "ikOverlayAlpha", + "boneSet": "fullBody" }, "children": [ { - "id": "ikOverlay", + "id": "ik", + "type": "inverseKinematics", + "data": { + "solutionSource": "relaxToUnderPoses", + "solutionSourceVar": "solutionSource", + "targets": [ + { + "jointName": "Hips", + "positionVar": "hipsPosition", + "rotationVar": "hipsRotation", + "typeVar": "hipsType", + "weightVar": "hipsWeight", + "weight": 1.0, + "flexCoefficients": [1] + }, + { + "jointName": "RightHand", + "positionVar": "rightHandPosition", + "rotationVar": "rightHandRotation", + "typeVar": "rightHandType", + "weightVar": "rightHandWeight", + "weight": 1.0, + "flexCoefficients": [1, 0.5, 0.5, 0.2, 0.01, 0.005, 0.001, 0.0, 0.0], + "poleVectorEnabledVar": "rightHandPoleVectorEnabled", + "poleReferenceVectorVar": "rightHandPoleReferenceVector", + "poleVectorVar": "rightHandPoleVector" + }, + { + "jointName": "LeftHand", + "positionVar": "leftHandPosition", + "rotationVar": "leftHandRotation", + "typeVar": "leftHandType", + "weightVar": "leftHandWeight", + "weight": 1.0, + "flexCoefficients": [1, 0.5, 0.5, 0.2, 0.01, 0.005, 0.001, 0.0, 0.0], + "poleVectorEnabledVar": "leftHandPoleVectorEnabled", + "poleReferenceVectorVar": "leftHandPoleReferenceVector", + "poleVectorVar": "leftHandPoleVector" + }, + { + "jointName": "Spine2", + "positionVar": "spine2Position", + "rotationVar": "spine2Rotation", + "typeVar": "spine2Type", + "weightVar": "spine2Weight", + "weight": 2.0, + "flexCoefficients": [1.0, 0.5, 0.25] + }, + { + "jointName": "Head", + "positionVar": "headPosition", + "rotationVar": "headRotation", + "typeVar": "headType", + "weightVar": "headWeight", + "weight": 4.0, + "flexCoefficients": [1, 0.5, 0.25, 0.2, 0.1] + } + ] + }, + "children": [] + }, + { + "id": "defaultPoseOverlay", "type": "overlay", "data": { - "alpha": 1.0, - "alphaVar": "ikOverlayAlpha", - "boneSet": "fullBody" + "alpha": 0.0, + "alphaVar": "defaultPoseOverlayAlpha", + "boneSet": "fullBody", + "boneSetVar": "defaultPoseOverlayBoneSet" }, "children": [ { - "id": "ik", - "type": "inverseKinematics", + "id": "defaultPose", + "type": "defaultPose", "data": { - "solutionSource": "relaxToUnderPoses", - "solutionSourceVar": "solutionSource", - "targets": [ - { - "jointName": "Hips", - "positionVar": "hipsPosition", - "rotationVar": "hipsRotation", - "typeVar": "hipsType", - "weightVar": "hipsWeight", - "weight": 1.0, - "flexCoefficients": [ 1 ] - }, - { - "jointName": "RightHand", - "positionVar": "rightHandPosition", - "rotationVar": "rightHandRotation", - "typeVar": "rightHandType", - "weightVar": "rightHandWeight", - "weight": 1.0, - "flexCoefficients": [ 1, 0.5, 0.5, 0.2, 0.01, 0.005, 0.001, 0.0, 0.0 ], - "poleVectorEnabledVar": "rightHandPoleVectorEnabled", - "poleReferenceVectorVar": "rightHandPoleReferenceVector", - "poleVectorVar": "rightHandPoleVector" - }, - { - "jointName": "LeftHand", - "positionVar": "leftHandPosition", - "rotationVar": "leftHandRotation", - "typeVar": "leftHandType", - "weightVar": "leftHandWeight", - "weight": 1.0, - "flexCoefficients": [ 1, 0.5, 0.5, 0.2, 0.01, 0.005, 0.001, 0.0, 0.0 ], - "poleVectorEnabledVar": "leftHandPoleVectorEnabled", - "poleReferenceVectorVar": "leftHandPoleReferenceVector", - "poleVectorVar": "leftHandPoleVector" - } - ] }, "children": [] }, { - "id": "defaultPoseOverlay", + "id": "rightHandOverlay", "type": "overlay", "data": { "alpha": 0.0, - "alphaVar": "defaultPoseOverlayAlpha", - "boneSet": "fullBody", - "boneSetVar": "defaultPoseOverlayBoneSet" + "boneSet": "rightHand", + "alphaVar": "rightHandOverlayAlpha" }, "children": [ { - "id": "defaultPose", - "type": "defaultPose", + "id": "rightHandStateMachine", + "type": "stateMachine", "data": { - }, - "children": [] - }, - { - "id": "rightHandOverlay", - "type": "overlay", - "data": { - "alpha": 0.0, - "boneSet": "rightHand", - "alphaVar": "rightHandOverlayAlpha" + "currentState": "rightHandGrasp", + "states": [ + { + "id": "rightHandGrasp", + "interpTarget": 3, + "interpDuration": 3, + "transitions": [ + { "var": "isRightIndexPoint", "state": "rightIndexPoint" }, + { "var": "isRightThumbRaise", "state": "rightThumbRaise" }, + { "var": "isRightIndexPointAndThumbRaise", "state": "rightIndexPointAndThumbRaise" } + ] + }, + { + "id": "rightIndexPoint", + "interpTarget": 15, + "interpDuration": 3, + "transitions": [ + { "var": "isRightHandGrasp", "state": "rightHandGrasp" }, + { "var": "isRightThumbRaise", "state": "rightThumbRaise" }, + { "var": "isRightIndexPointAndThumbRaise", "state": "rightIndexPointAndThumbRaise" } + ] + }, + { + "id": "rightThumbRaise", + "interpTarget": 15, + "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" } + ] + } + ] }, "children": [ { - "id": "rightHandStateMachine", + "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", "type": "stateMachine", "data": { - "currentState": "rightHandGrasp", + "currentState": "leftHandGrasp", "states": [ { - "id": "rightHandGrasp", + "id": "leftHandGrasp", "interpTarget": 3, "interpDuration": 3, "transitions": [ - { - "var": "isRightIndexPoint", - "state": "rightIndexPoint" - }, - { - "var": "isRightThumbRaise", - "state": "rightThumbRaise" - }, - { - "var": "isRightIndexPointAndThumbRaise", - "state": "rightIndexPointAndThumbRaise" - } + { "var": "isLeftIndexPoint", "state": "leftIndexPoint" }, + { "var": "isLeftThumbRaise", "state": "leftThumbRaise" }, + { "var": "isLeftIndexPointAndThumbRaise", "state": "leftIndexPointAndThumbRaise" } ] }, { - "id": "rightIndexPoint", + "id": "leftIndexPoint", "interpTarget": 15, "interpDuration": 3, "transitions": [ - { - "var": "isRightHandGrasp", - "state": "rightHandGrasp" - }, - { - "var": "isRightThumbRaise", - "state": "rightThumbRaise" - }, - { - "var": "isRightIndexPointAndThumbRaise", - "state": "rightIndexPointAndThumbRaise" - } + { "var": "isLeftHandGrasp", "state": "leftHandGrasp" }, + { "var": "isLeftThumbRaise", "state": "leftThumbRaise" }, + { "var": "isLeftIndexPointAndThumbRaise", "state": "leftIndexPointAndThumbRaise" } ] }, { - "id": "rightThumbRaise", + "id": "leftThumbRaise", "interpTarget": 15, "interpDuration": 3, "transitions": [ - { - "var": "isRightHandGrasp", - "state": "rightHandGrasp" - }, - { - "var": "isRightIndexPoint", - "state": "rightIndexPoint" - }, - { - "var": "isRightIndexPointAndThumbRaise", - "state": "rightIndexPointAndThumbRaise" - } + { "var": "isLeftHandGrasp", "state": "leftHandGrasp" }, + { "var": "isLeftIndexPoint", "state": "leftIndexPoint" }, + { "var": "isLeftIndexPointAndThumbRaise", "state": "leftIndexPointAndThumbRaise" } ] }, { - "id": "rightIndexPointAndThumbRaise", + "id": "leftIndexPointAndThumbRaise", "interpTarget": 15, "interpDuration": 3, "transitions": [ - { - "var": "isRightHandGrasp", - "state": "rightHandGrasp" - }, - { - "var": "isRightIndexPoint", - "state": "rightIndexPoint" - }, - { - "var": "isRightThumbRaise", - "state": "rightThumbRaise" - } + { "var": "isLeftHandGrasp", "state": "leftHandGrasp" }, + { "var": "isLeftIndexPoint", "state": "leftIndexPoint" }, + { "var": "isLeftThumbRaise", "state": "leftThumbRaise" } ] } ] }, "children": [ { - "id": "rightHandGrasp", + "id": "leftHandGrasp", "type": "blendLinear", "data": { "alpha": 0.0, - "alphaVar": "rightHandGraspAlpha" + "alphaVar": "leftHandGraspAlpha" }, "children": [ { - "id": "rightHandGraspOpen", + "id": "leftHandGraspOpen", "type": "clip", "data": { - "url": "qrc:///avatar/animations/hydra_pose_open_right.fbx", + "url": "qrc:///avatar/animations/hydra_pose_open_left.fbx", "startFrame": 0.0, "endFrame": 0.0, "timeScale": 1.0, @@ -296,12 +459,12 @@ "children": [] }, { - "id": "rightHandGraspClosed", + "id": "leftHandGraspClosed", "type": "clip", "data": { - "url": "qrc:///avatar/animations/hydra_pose_closed_right.fbx", - "startFrame": 0.0, - "endFrame": 0.0, + "url": "qrc:///avatar/animations/hydra_pose_closed_left.fbx", + "startFrame": 10.0, + "endFrame": 10.0, "timeScale": 1.0, "loopFlag": true }, @@ -310,18 +473,18 @@ ] }, { - "id": "rightIndexPoint", + "id": "leftIndexPoint", "type": "blendLinear", - "data": { + "data": { "alpha": 0.0, - "alphaVar": "rightHandGraspAlpha" + "alphaVar": "leftHandGraspAlpha" }, "children": [ { - "id": "rightIndexPointOpen", + "id": "leftIndexPointOpen", "type": "clip", "data": { - "url": "qrc:///avatar/animations/touch_point_open_right.fbx", + "url": "qrc:///avatar/animations/touch_point_open_left.fbx", "startFrame": 15.0, "endFrame": 15.0, "timeScale": 1.0, @@ -330,10 +493,10 @@ "children": [] }, { - "id": "rightIndexPointClosed", + "id": "leftIndexPointClosed", "type": "clip", "data": { - "url": "qrc:///avatar/animations/touch_point_closed_right.fbx", + "url": "qrc:///avatar/animations/touch_point_closed_left.fbx", "startFrame": 15.0, "endFrame": 15.0, "timeScale": 1.0, @@ -344,18 +507,18 @@ ] }, { - "id": "rightThumbRaise", + "id": "leftThumbRaise", "type": "blendLinear", - "data": { + "data": { "alpha": 0.0, - "alphaVar": "rightHandGraspAlpha" + "alphaVar": "leftHandGraspAlpha" }, "children": [ { - "id": "rightThumbRaiseOpen", + "id": "leftThumbRaiseOpen", "type": "clip", "data": { - "url": "qrc:///avatar/animations/touch_thumb_open_right.fbx", + "url": "qrc:///avatar/animations/touch_thumb_open_left.fbx", "startFrame": 15.0, "endFrame": 15.0, "timeScale": 1.0, @@ -364,10 +527,10 @@ "children": [] }, { - "id": "rightThumbRaiseClosed", + "id": "leftThumbRaiseClosed", "type": "clip", "data": { - "url": "qrc:///avatar/animations/touch_thumb_closed_right.fbx", + "url": "qrc:///avatar/animations/touch_thumb_closed_left.fbx", "startFrame": 15.0, "endFrame": 15.0, "timeScale": 1.0, @@ -378,18 +541,18 @@ ] }, { - "id": "rightIndexPointAndThumbRaise", + "id": "leftIndexPointAndThumbRaise", "type": "blendLinear", - "data": { + "data": { "alpha": 0.0, - "alphaVar": "rightHandGraspAlpha" + "alphaVar": "leftHandGraspAlpha" }, "children": [ { - "id": "rightIndexPointAndThumbRaiseOpen", + "id": "leftIndexPointAndThumbRaiseOpen", "type": "clip", "data": { - "url": "qrc:///avatar/animations/touch_thumb_point_open_right.fbx", + "url": "qrc:///avatar/animations/touch_thumb_point_open_left.fbx", "startFrame": 15.0, "endFrame": 15.0, "timeScale": 1.0, @@ -398,10 +561,10 @@ "children": [] }, { - "id": "rightIndexPointAndThumbRaiseClosed", + "id": "leftIndexPointAndThumbRaiseClosed", "type": "clip", "data": { - "url": "qrc:///avatar/animations/touch_thumb_point_closed_right.fbx", + "url": "qrc:///avatar/animations/touch_thumb_point_closed_left.fbx", "startFrame": 15.0, "endFrame": 15.0, "timeScale": 1.0, @@ -414,1312 +577,654 @@ ] }, { - "id": "leftHandOverlay", - "type": "overlay", + "id": "mainStateMachine", + "type": "stateMachine", "data": { - "alpha": 0.0, - "boneSet": "leftHand", - "alphaVar": "leftHandOverlayAlpha" + "outputJoints": ["LeftFoot", "RightFoot"], + "currentState": "idle", + "states": [ + { + "id": "idle", + "interpTarget": 20, + "interpDuration": 8, + "interpType": "snapshotPrev", + "transitions": [ + { "var": "isMovingForward", "state": "WALKFWD" }, + { "var": "isMovingBackward", "state": "WALKBWD" }, + { "var": "isMovingRight", "state": "STRAFERIGHT" }, + { "var": "isMovingLeft", "state": "STRAFELEFT" }, + { "var": "isTurningRight", "state": "turnRight" }, + { "var": "isTurningLeft", "state": "turnLeft" }, + { "var": "isFlying", "state": "fly" }, + { "var": "isTakeoffStand", "state": "takeoffStand" }, + { "var": "isTakeoffRun", "state": "TAKEOFFRUN" }, + { "var": "isInAirStand", "state": "inAirStand" }, + { "var": "isInAirRun", "state": "INAIRRUN" }, + { "var": "isMovingRightHmd", "state": "strafeRightHmd" }, + { "var": "isMovingLeftHmd", "state": "strafeLeftHmd" } + ] + }, + { + "id": "idleToWalkFwd", + "interpTarget": 12, + "interpDuration": 8, + "transitions": [ + { "var": "idleToWalkFwdOnDone", "state": "WALKFWD" }, + { "var": "isNotMoving", "state": "idle" }, + { "var": "isMovingBackward", "state": "WALKBWD" }, + { "var": "isMovingRight", "state": "STRAFERIGHT" }, + { "var": "isMovingLeft", "state": "STRAFELEFT" }, + { "var": "isTurningRight", "state": "turnRight" }, + { "var": "isTurningLeft", "state": "turnLeft" }, + { "var": "isFlying", "state": "fly" }, + { "var": "isTakeoffStand", "state": "takeoffStand" }, + { "var": "isTakeoffRun", "state": "TAKEOFFRUN" }, + { "var": "isInAirStand", "state": "inAirStand" }, + { "var": "isInAirRun", "state": "INAIRRUN" }, + { "var": "isMovingRightHmd", "state": "strafeRightHmd" }, + { "var": "isMovingLeftHmd", "state": "strafeLeftHmd" } + ] + }, + { + "id": "idleSettle", + "interpTarget": 15, + "interpDuration": 8, + "interpType": "snapshotPrev", + "transitions": [ + {"var": "idleSettleOnDone", "state": "idle" }, + {"var": "isMovingForward", "state": "WALKFWD" }, + { "var": "isMovingBackward", "state": "WALKBWD" }, + { "var": "isMovingRight", "state": "STRAFERIGHT" }, + { "var": "isMovingLeft", "state": "STRAFELEFT" }, + { "var": "isMovingRightHmd", "state": "strafeRightHmd" }, + { "var": "isMovingLeftHmd", "state": "strafeLeftHmd" }, + { "var": "isTurningRight", "state": "turnRight" }, + { "var": "isTurningLeft", "state": "turnLeft" }, + { "var": "isFlying", "state": "fly" }, + { "var": "isTakeoffStand", "state": "takeoffStand" }, + { "var": "isTakeoffRun", "state": "TAKEOFFRUN" }, + { "var": "isInAirStand", "state": "inAirStand" }, + { "var": "isInAirRun", "state": "INAIRRUN" } + ] + }, + { + "id": "WALKFWD", + "interpTarget": 35, + "interpDuration": 10, + "interpType": "snapshotPrev", + "transitions": [ + { "var": "isNotMoving", "state": "idleSettle" }, + { "var": "isMovingBackward", "state": "WALKBWD" }, + { "var": "isMovingRight", "state": "STRAFERIGHT" }, + { "var": "isMovingLeft", "state": "STRAFELEFT" }, + { "var": "isTurningRight", "state": "turnRight" }, + { "var": "isTurningLeft", "state": "turnLeft" }, + { "var": "isFlying", "state": "fly" }, + { "var": "isTakeoffStand", "state": "takeoffStand" }, + { "var": "isTakeoffRun", "state": "TAKEOFFRUN" }, + { "var": "isInAirStand", "state": "inAirStand" }, + { "var": "isInAirRun", "state": "INAIRRUN" }, + { "var": "isMovingRightHmd", "state": "strafeRightHmd" }, + { "var": "isMovingLeftHmd", "state": "strafeLeftHmd" } + ] + }, + { + "id": "WALKBWD", + "interpTarget": 35, + "interpDuration": 10, + "interpType": "snapshotPrev", + "transitions": [ + { "var": "isNotMoving", "state": "idleSettle" }, + { "var": "isMovingForward", "state": "WALKFWD" }, + { "var": "isMovingRight", "state": "STRAFERIGHT" }, + { "var": "isMovingLeft", "state": "STRAFELEFT" }, + { "var": "isTurningRight", "state": "turnRight" }, + { "var": "isTurningLeft", "state": "turnLeft" }, + { "var": "isFlying", "state": "fly" }, + { "var": "isTakeoffStand", "state": "takeoffStand" }, + { "var": "isTakeoffRun", "state": "TAKEOFFRUN" }, + { "var": "isInAirStand", "state": "inAirStand" }, + { "var": "isInAirRun", "state": "INAIRRUN" }, + { "var": "isMovingRightHmd", "state": "strafeRightHmd" }, + { "var": "isMovingLeftHmd", "state": "strafeLeftHmd" } + ] + }, + { + "id": "STRAFERIGHT", + "interpTarget": 25, + "interpDuration": 8, + "interpType": "snapshotPrev", + "transitions": [ + { "var": "isNotMoving", "state": "idleSettle" }, + { "var": "isMovingForward", "state": "WALKFWD" }, + { "var": "isMovingBackward", "state": "WALKBWD" }, + { "var": "isMovingLeft", "state": "STRAFELEFT" }, + { "var": "isTurningRight", "state": "turnRight" }, + { "var": "isTurningLeft", "state": "turnLeft" }, + { "var": "isFlying", "state": "fly" }, + { "var": "isTakeoffStand", "state": "takeoffStand" }, + { "var": "isTakeoffRun", "state": "TAKEOFFRUN" }, + { "var": "isInAirStand", "state": "inAirStand" }, + { "var": "isInAirRun", "state": "INAIRRUN" }, + { "var": "isMovingRightHmd", "state": "strafeRightHmd" }, + { "var": "isMovingLeftHmd", "state": "strafeLeftHmd" } + ] + }, + { + "id": "STRAFELEFT", + "interpTarget": 25, + "interpDuration": 8, + "interpType": "snapshotPrev", + "transitions": [ + { "var": "isNotMoving", "state": "idleSettle" }, + { "var": "isMovingForward", "state": "WALKFWD" }, + { "var": "isMovingBackward", "state": "WALKBWD" }, + { "var": "isMovingRight", "state": "STRAFERIGHT" }, + { "var": "isTurningRight", "state": "turnRight" }, + { "var": "isTurningLeft", "state": "turnLeft" }, + { "var": "isFlying", "state": "fly" }, + { "var": "isTakeoffStand", "state": "takeoffStand" }, + { "var": "isTakeoffRun", "state": "TAKEOFFRUN" }, + { "var": "isInAirStand", "state": "inAirStand" }, + { "var": "isInAirRun", "state": "INAIRRUN" }, + { "var": "isMovingRightHmd", "state": "strafeRightHmd" }, + { "var": "isMovingLeftHmd", "state": "strafeLeftHmd" } + ] + }, + { + "id": "turnRight", + "interpTarget": 6, + "interpDuration": 8, + "transitions": [ + { "var": "isNotTurning", "state": "idle" }, + { "var": "isMovingForward", "state": "WALKFWD" }, + { "var": "isMovingBackward", "state": "WALKBWD" }, + { "var": "isMovingRight", "state": "STRAFERIGHT" }, + { "var": "isMovingLeft", "state": "STRAFELEFT" }, + { "var": "isTurningLeft", "state": "turnLeft" }, + { "var": "isFlying", "state": "fly" }, + { "var": "isTakeoffStand", "state": "takeoffStand" }, + { "var": "isTakeoffRun", "state": "TAKEOFFRUN" }, + { "var": "isInAirStand", "state": "inAirStand" }, + { "var": "isInAirRun", "state": "INAIRRUN" }, + { "var": "isMovingRightHmd", "state": "strafeRightHmd" }, + { "var": "isMovingLeftHmd", "state": "strafeLeftHmd" } + ] + }, + { + "id": "turnLeft", + "interpTarget": 6, + "interpDuration": 8, + "transitions": [ + { "var": "isNotTurning", "state": "idle" }, + { "var": "isMovingForward", "state": "WALKFWD" }, + { "var": "isMovingBackward", "state": "WALKBWD" }, + { "var": "isMovingRight", "state": "STRAFERIGHT" }, + { "var": "isMovingLeft", "state": "STRAFELEFT" }, + { "var": "isTurningRight", "state": "turnRight" }, + { "var": "isFlying", "state": "fly" }, + { "var": "isTakeoffStand", "state": "takeoffStand" }, + { "var": "isTakeoffRun", "state": "TAKEOFFRUN" }, + { "var": "isInAirStand", "state": "inAirStand" }, + { "var": "isInAirRun", "state": "INAIRRUN" }, + { "var": "isMovingRightHmd", "state": "strafeRightHmd" }, + { "var": "isMovingLeftHmd", "state": "strafeLeftHmd" } + ] + }, + { + "id": "strafeRightHmd", + "interpTarget": 5, + "interpDuration": 8, + "interpType": "snapshotPrev", + "transitions": [ + { "var": "isNotMoving", "state": "idleSettle" }, + { "var": "isMovingForward", "state": "WALKFWD" }, + { "var": "isMovingBackward", "state": "WALKBWD" }, + { "var": "isMovingLeftHmd", "state": "strafeLeftHmd" }, + { "var": "isMovingRight", "state": "STRAFERIGHT" }, + { "var": "isMovingLeft", "state": "STRAFELEFT" }, + { "var": "isTurningRight", "state": "turnRight" }, + { "var": "isTurningLeft", "state": "turnLeft" }, + { "var": "isFlying", "state": "fly" }, + { "var": "isTakeoffStand", "state": "takeoffStand" }, + { "var": "isTakeoffRun", "state": "TAKEOFFRUN" }, + { "var": "isInAirStand", "state": "inAirStand" }, + { "var": "isInAirRun", "state": "INAIRRUN" } + ] + }, + { + "id": "strafeLeftHmd", + "interpTarget": 5, + "interpDuration": 8, + "interpType": "snapshotPrev", + "transitions": [ + { "var": "isNotMoving", "state": "idleSettle" }, + { "var": "isMovingForward", "state": "WALKFWD" }, + { "var": "isMovingBackward", "state": "WALKBWD" }, + { "var": "isMovingRightHmd", "state": "strafeRightHmd" }, + { "var": "isMovingRight", "state": "STRAFERIGHT" }, + { "var": "isMovingLeft", "state": "STRAFELEFT" }, + { "var": "isTurningRight", "state": "turnRight" }, + { "var": "isTurningLeft", "state": "turnLeft" }, + { "var": "isFlying", "state": "fly" }, + { "var": "isTakeoffStand", "state": "takeoffStand" }, + { "var": "isTakeoffRun", "state": "TAKEOFFRUN" }, + { "var": "isInAirStand", "state": "inAirStand" }, + { "var": "isInAirRun", "state": "INAIRRUN" } + ] + }, + { + "id": "fly", + "interpTarget": 6, + "interpDuration": 6, + "transitions": [ + { "var": "isNotFlying", "state": "idleSettle" } + ] + }, + { + "id": "takeoffStand", + "interpTarget": 2, + "interpDuration": 2, + "transitions": [ + { "var": "isNotTakeoff", "state": "inAirStand" } + ] + }, + { + "id": "TAKEOFFRUN", + "interpTarget": 2, + "interpDuration": 2, + "transitions": [ + { "var": "isNotTakeoff", "state": "INAIRRUN" } + ] + }, + { + "id": "inAirStand", + "interpTarget": 3, + "interpDuration": 3, + "interpType": "snapshotPrev", + "transitions": [ + { "var": "isNotInAir", "state": "landStandImpact" } + ] + }, + { + "id": "INAIRRUN", + "interpTarget": 3, + "interpDuration": 3, + "interpType": "snapshotPrev", + "transitions": [ + { "var": "isNotInAir", "state": "WALKFWD" } + ] + }, + { + "id": "landStandImpact", + "interpTarget": 1, + "interpDuration": 1, + "transitions": [ + { "var": "isFlying", "state": "fly" }, + { "var": "isTakeoffStand", "state": "takeoffStand" }, + { "var": "isTakeoffRun", "state": "TAKEOFFRUN" }, + { "var": "landStandImpactOnDone", "state": "landStand" } + ] + }, + { + "id": "landStand", + "interpTarget": 1, + "interpDuration": 1, + "transitions": [ + { "var": "isMovingForward", "state": "WALKFWD" }, + { "var": "isMovingBackward", "state": "WALKBWD" }, + { "var": "isMovingRight", "state": "STRAFERIGHT" }, + { "var": "isMovingLeft", "state": "STRAFELEFT" }, + { "var": "isTurningRight", "state": "turnRight" }, + { "var": "isTurningLeft", "state": "turnLeft" }, + { "var": "isFlying", "state": "fly" }, + { "var": "isTakeoffStand", "state": "takeoffStand" }, + { "var": "isTakeoffRun", "state": "TAKEOFFRUN" }, + { "var": "isInAirStand", "state": "inAirStand" }, + { "var": "isInAirRun", "state": "INAIRRUN" }, + { "var": "landStandOnDone", "state": "idle" }, + { "var": "isMovingRightHmd", "state": "strafeRightHmd" }, + { "var": "isMovingLeftHmd", "state": "strafeLeftHmd" } + ] + }, + { + "id": "LANDRUN", + "interpTarget": 2, + "interpDuration": 2, + "transitions": [ + { "var": "isFlying", "state": "fly" }, + { "var": "isTakeoffStand", "state": "takeoffStand" }, + { "var": "isTakeoffRun", "state": "TAKEOFFRUN" }, + { "var": "landRunOnDone", "state": "WALKFWD" } + ] + } + ] }, "children": [ { - "id": "leftHandStateMachine", + "id": "idle", "type": "stateMachine", "data": { - "currentState": "leftHandGrasp", + "currentState": "idleStand", "states": [ { - "id": "leftHandGrasp", - "interpTarget": 3, - "interpDuration": 3, + "id": "idleStand", + "interpTarget": 6, + "interpDuration": 10, "transitions": [ - { - "var": "isLeftIndexPoint", - "state": "leftIndexPoint" - }, - { - "var": "isLeftThumbRaise", - "state": "leftThumbRaise" - }, - { - "var": "isLeftIndexPointAndThumbRaise", - "state": "leftIndexPointAndThumbRaise" - } + { "var": "isTalking", "state": "idleTalk" } ] }, { - "id": "leftIndexPoint", - "interpTarget": 15, - "interpDuration": 3, + "id": "idleTalk", + "interpTarget": 6, + "interpDuration": 10, "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" - } + { "var": "notIsTalking", "state": "idleStand" } ] } ] }, "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": "mainStateMachine", - "type": "stateMachine", - "data": { - "outputJoints": [ "LeftFoot", "RightFoot" ], - "currentState": "idle", - "states": [ - { - "id": "idle", - "interpTarget": 20, - "interpDuration": 8, - "interpType": "snapshotPrev", - "transitions": [ - { - "var": "isMovingForward", - "state": "WALKFWD" - }, - { - "var": "isMovingBackward", - "state": "WALKBWD" - }, - { - "var": "isMovingRight", - "state": "STRAFERIGHT" - }, - { - "var": "isMovingLeft", - "state": "STRAFELEFT" - }, - { - "var": "isTurningRight", - "state": "turnRight" - }, - { - "var": "isTurningLeft", - "state": "turnLeft" - }, - { - "var": "isFlying", - "state": "fly" - }, - { - "var": "isTakeoffStand", - "state": "takeoffStand" - }, - { - "var": "isTakeoffRun", - "state": "TAKEOFFRUN" - }, - { - "var": "isInAirStand", - "state": "inAirStand" - }, - { - "var": "isInAirRun", - "state": "INAIRRUN" - }, - { - "var": "isMovingRightHmd", - "state": "strafeRightHmd" - }, - { - "var": "isMovingLeftHmd", - "state": "strafeLeftHmd" - } - ] - }, - { - "id": "idleToWalkFwd", - "interpTarget": 12, - "interpDuration": 8, - "transitions": [ - { - "var": "idleToWalkFwdOnDone", - "state": "WALKFWD" - }, - { - "var": "isNotMoving", - "state": "idle" - }, - { - "var": "isMovingBackward", - "state": "WALKBWD" - }, - { - "var": "isMovingRight", - "state": "STRAFERIGHT" - }, - { - "var": "isMovingLeft", - "state": "STRAFELEFT" - }, - { - "var": "isTurningRight", - "state": "turnRight" - }, - { - "var": "isTurningLeft", - "state": "turnLeft" - }, - { - "var": "isFlying", - "state": "fly" - }, - { - "var": "isTakeoffStand", - "state": "takeoffStand" - }, - { - "var": "isTakeoffRun", - "state": "TAKEOFFRUN" - }, - { - "var": "isInAirStand", - "state": "inAirStand" - }, - { - "var": "isInAirRun", - "state": "INAIRRUN" - }, - { - "var": "isMovingRightHmd", - "state": "strafeRightHmd" - }, - { - "var": "isMovingLeftHmd", - "state": "strafeLeftHmd" - } - ] - }, - { - "id": "idleSettle", - "interpTarget": 15, - "interpDuration": 8, - "interpType": "snapshotPrev", - "transitions": [ - { - "var": "idleSettleOnDone", - "state": "idle" - }, - { - "var": "isMovingForward", - "state": "WALKFWD" - }, - { - "var": "isMovingBackward", - "state": "WALKBWD" - }, - { - "var": "isMovingRight", - "state": "STRAFERIGHT" - }, - { - "var": "isMovingLeft", - "state": "STRAFELEFT" - }, - { - "var": "isMovingRightHmd", - "state": "strafeRightHmd" - }, - { - "var": "isMovingLeftHmd", - "state": "strafeLeftHmd" - }, - { - "var": "isTurningRight", - "state": "turnRight" - }, - { - "var": "isTurningLeft", - "state": "turnLeft" - }, - { - "var": "isFlying", - "state": "fly" - }, - { - "var": "isTakeoffStand", - "state": "takeoffStand" - }, - { - "var": "isTakeoffRun", - "state": "TAKEOFFRUN" - }, - { - "var": "isInAirStand", - "state": "inAirStand" - }, - { - "var": "isInAirRun", - "state": "INAIRRUN" - } - ] - }, - { - "id": "WALKFWD", - "interpTarget": 35, - "interpDuration": 10, - "interpType": "snapshotPrev", - "transitions": [ - { - "var": "isNotMoving", - "state": "idleSettle" - }, - { - "var": "isMovingBackward", - "state": "WALKBWD" - }, - { - "var": "isMovingRight", - "state": "STRAFERIGHT" - }, - { - "var": "isMovingLeft", - "state": "STRAFELEFT" - }, - { - "var": "isTurningRight", - "state": "turnRight" - }, - { - "var": "isTurningLeft", - "state": "turnLeft" - }, - { - "var": "isFlying", - "state": "fly" - }, - { - "var": "isTakeoffStand", - "state": "takeoffStand" - }, - { - "var": "isTakeoffRun", - "state": "TAKEOFFRUN" - }, - { - "var": "isInAirStand", - "state": "inAirStand" - }, - { - "var": "isInAirRun", - "state": "INAIRRUN" - }, - { - "var": "isMovingRightHmd", - "state": "strafeRightHmd" - }, - { - "var": "isMovingLeftHmd", - "state": "strafeLeftHmd" - } - ] - }, - { - "id": "WALKBWD", - "interpTarget": 35, - "interpDuration": 10, - "interpType": "snapshotPrev", - "transitions": [ - { - "var": "isNotMoving", - "state": "idleSettle" - }, - { - "var": "isMovingForward", - "state": "WALKFWD" - }, - { - "var": "isMovingRight", - "state": "STRAFERIGHT" - }, - { - "var": "isMovingLeft", - "state": "STRAFELEFT" - }, - { - "var": "isTurningRight", - "state": "turnRight" - }, - { - "var": "isTurningLeft", - "state": "turnLeft" - }, - { - "var": "isFlying", - "state": "fly" - }, - { - "var": "isTakeoffStand", - "state": "takeoffStand" - }, - { - "var": "isTakeoffRun", - "state": "TAKEOFFRUN" - }, - { - "var": "isInAirStand", - "state": "inAirStand" - }, - { - "var": "isInAirRun", - "state": "INAIRRUN" - }, - { - "var": "isMovingRightHmd", - "state": "strafeRightHmd" - }, - { - "var": "isMovingLeftHmd", - "state": "strafeLeftHmd" - } - ] - }, - { - "id": "STRAFERIGHT", - "interpTarget": 25, - "interpDuration": 8, - "interpType": "snapshotPrev", - "transitions": [ - { - "var": "isNotMoving", - "state": "idleSettle" - }, - { - "var": "isMovingForward", - "state": "WALKFWD" - }, - { - "var": "isMovingBackward", - "state": "WALKBWD" - }, - { - "var": "isMovingLeft", - "state": "STRAFELEFT" - }, - { - "var": "isTurningRight", - "state": "turnRight" - }, - { - "var": "isTurningLeft", - "state": "turnLeft" - }, - { - "var": "isFlying", - "state": "fly" - }, - { - "var": "isTakeoffStand", - "state": "takeoffStand" - }, - { - "var": "isTakeoffRun", - "state": "TAKEOFFRUN" - }, - { - "var": "isInAirStand", - "state": "inAirStand" - }, - { - "var": "isInAirRun", - "state": "INAIRRUN" - }, - { - "var": "isMovingRightHmd", - "state": "strafeRightHmd" - }, - { - "var": "isMovingLeftHmd", - "state": "strafeLeftHmd" - } - ] - }, - { - "id": "STRAFELEFT", - "interpTarget": 25, - "interpDuration": 8, - "interpType": "snapshotPrev", - "transitions": [ - { - "var": "isNotMoving", - "state": "idleSettle" - }, - { - "var": "isMovingForward", - "state": "WALKFWD" - }, - { - "var": "isMovingBackward", - "state": "WALKBWD" - }, - { - "var": "isMovingRight", - "state": "STRAFERIGHT" - }, - { - "var": "isTurningRight", - "state": "turnRight" - }, - { - "var": "isTurningLeft", - "state": "turnLeft" - }, - { - "var": "isFlying", - "state": "fly" - }, - { - "var": "isTakeoffStand", - "state": "takeoffStand" - }, - { - "var": "isTakeoffRun", - "state": "TAKEOFFRUN" - }, - { - "var": "isInAirStand", - "state": "inAirStand" - }, - { - "var": "isInAirRun", - "state": "INAIRRUN" - }, - { - "var": "isMovingRightHmd", - "state": "strafeRightHmd" - }, - { - "var": "isMovingLeftHmd", - "state": "strafeLeftHmd" - } - ] - }, - { - "id": "turnRight", - "interpTarget": 6, - "interpDuration": 8, - "transitions": [ - { - "var": "isNotTurning", - "state": "idle" - }, - { - "var": "isMovingForward", - "state": "WALKFWD" - }, - { - "var": "isMovingBackward", - "state": "WALKBWD" - }, - { - "var": "isMovingRight", - "state": "STRAFERIGHT" - }, - { - "var": "isMovingLeft", - "state": "STRAFELEFT" - }, - { - "var": "isTurningLeft", - "state": "turnLeft" - }, - { - "var": "isFlying", - "state": "fly" - }, - { - "var": "isTakeoffStand", - "state": "takeoffStand" - }, - { - "var": "isTakeoffRun", - "state": "TAKEOFFRUN" - }, - { - "var": "isInAirStand", - "state": "inAirStand" - }, - { - "var": "isInAirRun", - "state": "INAIRRUN" - }, - { - "var": "isMovingRightHmd", - "state": "strafeRightHmd" - }, - { - "var": "isMovingLeftHmd", - "state": "strafeLeftHmd" - } - ] - }, - { - "id": "turnLeft", - "interpTarget": 6, - "interpDuration": 8, - "transitions": [ - { - "var": "isNotTurning", - "state": "idle" - }, - { - "var": "isMovingForward", - "state": "WALKFWD" - }, - { - "var": "isMovingBackward", - "state": "WALKBWD" - }, - { - "var": "isMovingRight", - "state": "STRAFERIGHT" - }, - { - "var": "isMovingLeft", - "state": "STRAFELEFT" - }, - { - "var": "isTurningRight", - "state": "turnRight" - }, - { - "var": "isFlying", - "state": "fly" - }, - { - "var": "isTakeoffStand", - "state": "takeoffStand" - }, - { - "var": "isTakeoffRun", - "state": "TAKEOFFRUN" - }, - { - "var": "isInAirStand", - "state": "inAirStand" - }, - { - "var": "isInAirRun", - "state": "INAIRRUN" - }, - { - "var": "isMovingRightHmd", - "state": "strafeRightHmd" - }, - { - "var": "isMovingLeftHmd", - "state": "strafeLeftHmd" - } - ] - }, - { - "id": "strafeRightHmd", - "interpTarget": 5, - "interpDuration": 8, - "interpType": "snapshotPrev", - "transitions": [ - { - "var": "isNotMoving", - "state": "idleSettle" - }, - { - "var": "isMovingForward", - "state": "WALKFWD" - }, - { - "var": "isMovingBackward", - "state": "WALKBWD" - }, - { - "var": "isMovingLeftHmd", - "state": "strafeLeftHmd" - }, - { - "var": "isMovingRight", - "state": "STRAFERIGHT" - }, - { - "var": "isMovingLeft", - "state": "STRAFELEFT" - }, - { - "var": "isTurningRight", - "state": "turnRight" - }, - { - "var": "isTurningLeft", - "state": "turnLeft" - }, - { - "var": "isFlying", - "state": "fly" - }, - { - "var": "isTakeoffStand", - "state": "takeoffStand" - }, - { - "var": "isTakeoffRun", - "state": "TAKEOFFRUN" - }, - { - "var": "isInAirStand", - "state": "inAirStand" - }, - { - "var": "isInAirRun", - "state": "INAIRRUN" - } - ] - }, - { - "id": "strafeLeftHmd", - "interpTarget": 5, - "interpDuration": 8, - "interpType": "snapshotPrev", - "transitions": [ - { - "var": "isNotMoving", - "state": "idleSettle" - }, - { - "var": "isMovingForward", - "state": "WALKFWD" - }, - { - "var": "isMovingBackward", - "state": "WALKBWD" - }, - { - "var": "isMovingRightHmd", - "state": "strafeRightHmd" - }, - { - "var": "isMovingRight", - "state": "STRAFERIGHT" - }, - { - "var": "isMovingLeft", - "state": "STRAFELEFT" - }, - { - "var": "isTurningRight", - "state": "turnRight" - }, - { - "var": "isTurningLeft", - "state": "turnLeft" - }, - { - "var": "isFlying", - "state": "fly" - }, - { - "var": "isTakeoffStand", - "state": "takeoffStand" - }, - { - "var": "isTakeoffRun", - "state": "TAKEOFFRUN" - }, - { - "var": "isInAirStand", - "state": "inAirStand" - }, - { - "var": "isInAirRun", - "state": "INAIRRUN" - } - ] - }, - { - "id": "fly", - "interpTarget": 6, - "interpDuration": 6, - "transitions": [ - { - "var": "isNotFlying", - "state": "idleSettle" - } - ] - }, - { - "id": "takeoffStand", - "interpTarget": 2, - "interpDuration": 2, - "transitions": [ - { - "var": "isNotTakeoff", - "state": "inAirStand" - } - ] - }, - { - "id": "TAKEOFFRUN", - "interpTarget": 2, - "interpDuration": 2, - "transitions": [ - { - "var": "isNotTakeoff", - "state": "INAIRRUN" - } - ] - }, - { - "id": "inAirStand", - "interpTarget": 3, - "interpDuration": 3, - "interpType": "snapshotPrev", - "transitions": [ - { - "var": "isNotInAir", - "state": "landStandImpact" - } - ] - }, - { - "id": "INAIRRUN", - "interpTarget": 3, - "interpDuration": 3, - "interpType": "snapshotPrev", - "transitions": [ - { - "var": "isNotInAir", - "state": "WALKFWD" - } - ] - }, - { - "id": "landStandImpact", - "interpTarget": 1, - "interpDuration": 1, - "transitions": [ - { - "var": "isFlying", - "state": "fly" - }, - { - "var": "isTakeoffStand", - "state": "takeoffStand" - }, - { - "var": "isTakeoffRun", - "state": "TAKEOFFRUN" - }, - { - "var": "landStandImpactOnDone", - "state": "landStand" - } - ] - }, - { - "id": "landStand", - "interpTarget": 1, - "interpDuration": 1, - "transitions": [ - { - "var": "isMovingForward", - "state": "WALKFWD" - }, - { - "var": "isMovingBackward", - "state": "WALKBWD" - }, - { - "var": "isMovingRight", - "state": "STRAFERIGHT" - }, - { - "var": "isMovingLeft", - "state": "STRAFELEFT" - }, - { - "var": "isTurningRight", - "state": "turnRight" - }, - { - "var": "isTurningLeft", - "state": "turnLeft" - }, - { - "var": "isFlying", - "state": "fly" - }, - { - "var": "isTakeoffStand", - "state": "takeoffStand" - }, - { - "var": "isTakeoffRun", - "state": "TAKEOFFRUN" - }, - { - "var": "isInAirStand", - "state": "inAirStand" - }, - { - "var": "isInAirRun", - "state": "INAIRRUN" - }, - { - "var": "landStandOnDone", - "state": "idle" - }, - { - "var": "isMovingRightHmd", - "state": "strafeRightHmd" - }, - { - "var": "isMovingLeftHmd", - "state": "strafeLeftHmd" - } - ] - }, - { - "id": "LANDRUN", - "interpTarget": 2, - "interpDuration": 2, - "transitions": [ - { - "var": "isFlying", - "state": "fly" - }, - { - "var": "isTakeoffStand", - "state": "takeoffStand" - }, - { - "var": "isTakeoffRun", - "state": "TAKEOFFRUN" - }, - { - "var": "landRunOnDone", - "state": "WALKFWD" - } - ] - } - ] - }, - "children": [ - { - "id": "idle", - "type": "stateMachine", - "data": { - "currentState": "idleStand", - "states": [ - { - "id": "idleStand", - "interpTarget": 6, - "interpDuration": 10, - "transitions": [ - { - "var": "isTalking", - "state": "idleTalk" - } - ] - }, - { - "id": "idleTalk", - "interpTarget": 6, - "interpDuration": 10, - "transitions": [ - { - "var": "notIsTalking", - "state": "idleStand" - } - ] - } - ] - }, - "children": [ - { - "id": "idleStand", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/idle.fbx", - "startFrame": 0.0, - "endFrame": 300.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - }, - { - "id": "idleTalk", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/talk.fbx", - "startFrame": 0.0, - "endFrame": 800.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - } - ] - }, - { - "id": "WALKFWD", - "type": "blendLinearMove", - "data": { - "alpha": 0.0, - "desiredSpeed": 1.4, - "characteristicSpeeds": [ 0.5, 1.8, 2.3, 3.2, 4.5 ], - "alphaVar": "moveForwardAlpha", - "desiredSpeedVar": "moveForwardSpeed" - }, - "children": [ - { - "id": "walkFwdShort_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/walk_short_fwd.fbx", - "startFrame": 0.0, - "endFrame": 39.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - }, - { - "id": "walkFwdNormal_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/walk_fwd.fbx", - "startFrame": 0.0, - "endFrame": 30.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - }, - { - "id": "walkFwdFast_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/walk_fwd_fast.fbx", - "startFrame": 0.0, - "endFrame": 25.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - }, - { - "id": "walkFwdJog_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/jog_fwd.fbx", - "startFrame": 0.0, - "endFrame": 25.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - }, - { - "id": "walkFwdRun_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/run_fwd.fbx", - "startFrame": 0.0, - "endFrame": 21.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - } - ] - }, - { - "id": "idleToWalkFwd", + "id": "idleStand", "type": "clip", "data": { - "url": "qrc:///avatar/animations/idle_to_walk.fbx", - "startFrame": 1.0, - "endFrame": 13.0, - "timeScale": 1.0, - "loopFlag": false - }, - "children": [] - }, - { - "id": "idleSettle", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/settle_to_idle.fbx", - "startFrame": 1.0, - "endFrame": 59.0, - "timeScale": 1.0, - "loopFlag": false - }, - "children": [] - }, - { - "id": "WALKBWD", - "type": "blendLinearMove", - "data": { - "alpha": 0.0, - "desiredSpeed": 1.4, - "characteristicSpeeds": [ 0.6, 1.6, 2.3, 3.1 ], - "alphaVar": "moveBackwardAlpha", - "desiredSpeedVar": "moveBackwardSpeed" - }, - "children": [ - { - "id": "walkBwdShort_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/walk_short_bwd.fbx", - "startFrame": 0.0, - "endFrame": 38.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - }, - { - "id": "walkBwdFast_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/walk_bwd_fast.fbx", - "startFrame": 0.0, - "endFrame": 27.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - }, - { - "id": "jogBwd_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/jog_bwd.fbx", - "startFrame": 0.0, - "endFrame": 24.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - }, - { - "id": "runBwd_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/run_bwd.fbx", - "startFrame": 0.0, - "endFrame": 16.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - } - ] - }, - { - "id": "turnLeft", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/turn_left.fbx", + "url": "qrc:///avatar/animations/idle.fbx", "startFrame": 0.0, - "endFrame": 32.0, + "endFrame": 300.0, "timeScale": 1.0, "loopFlag": true }, "children": [] }, { - "id": "turnRight", + "id": "idleTalk", "type": "clip", "data": { - "url": "qrc:///avatar/animations/turn_left.fbx", + "url": "qrc:///avatar/animations/talk.fbx", "startFrame": 0.0, - "endFrame": 32.0, + "endFrame": 800.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + } + ] + }, + { + "id": "WALKFWD", + "type": "blendLinearMove", + "data": { + "alpha": 0.0, + "desiredSpeed": 1.4, + "characteristicSpeeds": [0.5, 1.8, 2.3, 3.2, 4.5], + "alphaVar": "moveForwardAlpha", + "desiredSpeedVar": "moveForwardSpeed" + }, + "children": [ + { + "id": "walkFwdShort_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/walk_short_fwd.fbx", + "startFrame": 0.0, + "endFrame": 39.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "walkFwdNormal_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/walk_fwd.fbx", + "startFrame": 0.0, + "endFrame": 30.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "walkFwdFast_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/walk_fwd_fast.fbx", + "startFrame": 0.0, + "endFrame": 25.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "walkFwdJog_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jog_fwd.fbx", + "startFrame": 0.0, + "endFrame": 25.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "walkFwdRun_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/run_fwd.fbx", + "startFrame": 0.0, + "endFrame": 21.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + } + ] + }, + { + "id": "idleToWalkFwd", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/idle_to_walk.fbx", + "startFrame": 1.0, + "endFrame": 13.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] + }, + { + "id": "idleSettle", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/settle_to_idle.fbx", + "startFrame": 1.0, + "endFrame": 59.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] + }, + { + "id": "WALKBWD", + "type": "blendLinearMove", + "data": { + "alpha": 0.0, + "desiredSpeed": 1.4, + "characteristicSpeeds": [0.6, 1.6, 2.3, 3.1], + "alphaVar": "moveBackwardAlpha", + "desiredSpeedVar": "moveBackwardSpeed" + }, + "children": [ + { + "id": "walkBwdShort_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/walk_short_bwd.fbx", + "startFrame": 0.0, + "endFrame": 38.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "walkBwdFast_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/walk_bwd_fast.fbx", + "startFrame": 0.0, + "endFrame": 27.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "jogBwd_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jog_bwd.fbx", + "startFrame": 0.0, + "endFrame": 24.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "runBwd_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/run_bwd.fbx", + "startFrame": 0.0, + "endFrame": 16.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + } + ] + }, + { + "id": "turnLeft", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/turn_left.fbx", + "startFrame": 0.0, + "endFrame": 32.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "turnRight", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/turn_left.fbx", + "startFrame": 0.0, + "endFrame": 32.0, + "timeScale": 1.0, + "loopFlag": true, + "mirrorFlag": true + }, + "children": [] + }, + { + "id": "STRAFELEFT", + "type": "blendLinearMove", + "data": { + "alpha": 0.0, + "desiredSpeed": 1.4, + "characteristicSpeeds": [0.1, 0.5, 1.0, 2.6, 3.0], + "alphaVar": "moveLateralAlpha", + "desiredSpeedVar": "moveLateralSpeed" + }, + "children": [ + { + "id": "strafeLeftShortStep_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/side_step_short_left.fbx", + "startFrame": 0.0, + "endFrame": 29.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "strafeLeftStep_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/side_step_left.fbx", + "startFrame": 0.0, + "endFrame": 20.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "strafeLeftWalk_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/walk_left.fbx", + "startFrame": 0.0, + "endFrame": 35.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "strafeLeftWalkFast_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/walk_left_fast.fbx", + "startFrame": 0.0, + "endFrame": 21.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "strafeLeftJog_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jog_left.fbx", + "startFrame": 0.0, + "endFrame": 24.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + } + ] + }, + { + "id": "STRAFERIGHT", + "type": "blendLinearMove", + "data": { + "alpha": 0.0, + "desiredSpeed": 1.4, + "characteristicSpeeds": [0.1, 0.5, 1.0, 2.6, 3.0], + "alphaVar": "moveLateralAlpha", + "desiredSpeedVar": "moveLateralSpeed" + }, + "children": [ { + "id": "strafeRightShortStep_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/side_step_short_left.fbx", + "startFrame": 0.0, + "endFrame": 29.0, "timeScale": 1.0, "loopFlag": true, "mirrorFlag": true @@ -1727,275 +1232,256 @@ "children": [] }, { - "id": "STRAFELEFT", - "type": "blendLinearMove", - "data": { - "alpha": 0.0, - "desiredSpeed": 1.4, - "characteristicSpeeds": [ 0.1, 0.5, 1.0, 2.6, 3.0 ], - "alphaVar": "moveLateralAlpha", - "desiredSpeedVar": "moveLateralSpeed" - }, - "children": [ - { - "id": "strafeLeftShortStep_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/side_step_short_left.fbx", - "startFrame": 0.0, - "endFrame": 29.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - }, - { - "id": "strafeLeftStep_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/side_step_left.fbx", - "startFrame": 0.0, - "endFrame": 20.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - }, - { - "id": "strafeLeftWalk_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/walk_left.fbx", - "startFrame": 0.0, - "endFrame": 35.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - }, - { - "id": "strafeLeftWalkFast_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/walk_left_fast.fbx", - "startFrame": 0.0, - "endFrame": 21.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - }, - { - "id": "strafeLeftJog_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/jog_left.fbx", - "startFrame": 0.0, - "endFrame": 24.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - } - ] - }, - { - "id": "STRAFERIGHT", - "type": "blendLinearMove", - "data": { - "alpha": 0.0, - "desiredSpeed": 1.4, - "characteristicSpeeds": [ 0.1, 0.5, 1.0, 2.6, 3.0 ], - "alphaVar": "moveLateralAlpha", - "desiredSpeedVar": "moveLateralSpeed" - }, - "children": [ - { - "id": "strafeRightShortStep_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/side_step_short_left.fbx", - "startFrame": 0.0, - "endFrame": 29.0, - "timeScale": 1.0, - "loopFlag": true, - "mirrorFlag": true - }, - "children": [] - }, - { - "id": "strafeRightStep_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/side_step_left.fbx", - "startFrame": 0.0, - "endFrame": 20.0, - "timeScale": 1.0, - "loopFlag": true, - "mirrorFlag": true - }, - "children": [] - }, - { - "id": "strafeRightWalk_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/walk_left.fbx", - "startFrame": 0.0, - "endFrame": 35.0, - "timeScale": 1.0, - "loopFlag": true, - "mirrorFlag": true - }, - "children": [] - }, - { - "id": "strafeRightFast_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/walk_left_fast.fbx", - "startFrame": 0.0, - "endFrame": 21.0, - "timeScale": 1.0, - "loopFlag": true, - "mirrorFlag": true - }, - "children": [] - }, - { - "id": "strafeRightJog_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/jog_left.fbx", - "startFrame": 0.0, - "endFrame": 24.0, - "timeScale": 1.0, - "loopFlag": true, - "mirrorFlag": true - }, - "children": [] - } - ] - }, - { - "id": "strafeLeftHmd", - "type": "blendLinearMove", - "data": { - "alpha": 0.0, - "desiredSpeed": 1.4, - "characteristicSpeeds": [ 0, 0.5, 2.5 ], - "alphaVar": "moveLateralAlpha", - "desiredSpeedVar": "moveLateralSpeed" - }, - "children": [ - { - "id": "stepLeftShort_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/side_step_short_left.fbx", - "startFrame": 0.0, - "endFrame": 29.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - }, - { - "id": "stepLeft_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/side_step_left.fbx", - "startFrame": 0.0, - "endFrame": 20.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - }, - { - "id": "strafeLeftAnim_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/side_step_left_fast.fbx", - "startFrame": 0.0, - "endFrame": 16.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - } - ] - }, - { - "id": "strafeRightHmd", - "type": "blendLinearMove", - "data": { - "alpha": 0.0, - "desiredSpeed": 1.4, - "characteristicSpeeds": [ 0, 0.5, 2.5 ], - "alphaVar": "moveLateralAlpha", - "desiredSpeedVar": "moveLateralSpeed" - }, - "children": [ - { - "id": "stepRightShort_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/side_step_short_left.fbx", - "startFrame": 0.0, - "endFrame": 29.0, - "timeScale": 1.0, - "loopFlag": true, - "mirrorFlag": true - }, - "children": [] - }, - { - "id": "stepRight_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/side_step_left.fbx", - "startFrame": 0.0, - "endFrame": 20.0, - "timeScale": 1.0, - "loopFlag": true, - "mirrorFlag": true - }, - "children": [] - }, - { - "id": "strafeRightAnim_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/side_step_left_fast.fbx", - "startFrame": 0.0, - "endFrame": 16.0, - "timeScale": 1.0, - "loopFlag": true, - "mirrorFlag": true - }, - "children": [] - } - ] - }, - { - "id": "fly", + "id": "strafeRightStep_c", "type": "clip", "data": { - "url": "qrc:///avatar/animations/fly.fbx", - "startFrame": 1.0, - "endFrame": 80.0, + "url": "qrc:///avatar/animations/side_step_left.fbx", + "startFrame": 0.0, + "endFrame": 20.0, + "timeScale": 1.0, + "loopFlag": true, + "mirrorFlag": true + }, + "children": [] + }, + { + "id": "strafeRightWalk_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/walk_left.fbx", + "startFrame": 0.0, + "endFrame": 35.0, + "timeScale": 1.0, + "loopFlag": true, + "mirrorFlag": true + }, + "children": [] + }, + { + "id": "strafeRightFast_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/walk_left_fast.fbx", + "startFrame": 0.0, + "endFrame": 21.0, + "timeScale": 1.0, + "loopFlag": true, + "mirrorFlag": true + }, + "children": [] + }, + { + "id": "strafeRightJog_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jog_left.fbx", + "startFrame": 0.0, + "endFrame": 24.0, + "timeScale": 1.0, + "loopFlag": true, + "mirrorFlag": true + }, + "children": [] + } + ] + }, + { + "id": "strafeLeftHmd", + "type": "blendLinearMove", + "data": { + "alpha": 0.0, + "desiredSpeed": 1.4, + "characteristicSpeeds": [0, 0.5, 2.5], + "alphaVar": "moveLateralAlpha", + "desiredSpeedVar": "moveLateralSpeed" + }, + "children": [ + { + "id": "stepLeftShort_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/side_step_short_left.fbx", + "startFrame": 0.0, + "endFrame": 29.0, "timeScale": 1.0, "loopFlag": true }, "children": [] }, { - "id": "takeoffStand", + "id": "stepLeft_c", "type": "clip", "data": { - "url": "qrc:///avatar/animations/jump_standing_launch.fbx", + "url": "qrc:///avatar/animations/side_step_left.fbx", + "startFrame": 0.0, + "endFrame": 20.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "strafeLeftAnim_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/side_step_left_fast.fbx", + "startFrame": 0.0, + "endFrame": 16.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + } + ] + }, + { + "id": "strafeRightHmd", + "type": "blendLinearMove", + "data": { + "alpha": 0.0, + "desiredSpeed": 1.4, + "characteristicSpeeds": [0, 0.5, 2.5], + "alphaVar": "moveLateralAlpha", + "desiredSpeedVar": "moveLateralSpeed" + }, + "children": [ + { + "id": "stepRightShort_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/side_step_short_left.fbx", + "startFrame": 0.0, + "endFrame": 29.0, + "timeScale": 1.0, + "loopFlag": true, + "mirrorFlag": true + }, + "children": [] + }, + { + "id": "stepRight_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/side_step_left.fbx", + "startFrame": 0.0, + "endFrame": 20.0, + "timeScale": 1.0, + "loopFlag": true, + "mirrorFlag": true + }, + "children": [] + }, + { + "id": "strafeRightAnim_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/side_step_left_fast.fbx", + "startFrame": 0.0, + "endFrame": 16.0, + "timeScale": 1.0, + "loopFlag": true, + "mirrorFlag": true + }, + "children": [] + } + ] + }, + { + "id": "fly", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/fly.fbx", + "startFrame": 1.0, + "endFrame": 80.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "takeoffStand", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jump_standing_launch.fbx", + "startFrame": 2.0, + "endFrame": 16.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] + }, + { + "id": "TAKEOFFRUN", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jump_running_launch_land.fbx", + "startFrame": 4.0, + "endFrame": 15.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] + }, + { + "id": "inAirStand", + "type": "blendLinear", + "data": { + "alpha": 0.0, + "alphaVar": "inAirAlpha" + }, + "children": [ + { + "id": "inAirStandPreApex", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jump_standing_apex.fbx", + "startFrame": 0.0, + "endFrame": 0.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] + }, + { + "id": "inAirStandApex", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jump_standing_apex.fbx", + "startFrame": 1.0, + "endFrame": 1.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] + }, + { + "id": "inAirStandPostApex", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jump_standing_apex.fbx", "startFrame": 2.0, + "endFrame": 2.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] + } + ] + }, + { + "id": "INAIRRUN", + "type": "blendLinear", + "data": { + "alpha": 0.0, + "alphaVar": "inAirAlpha" + }, + "children": [ + { + "id": "inAirRunPreApex", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jump_running_launch_land.fbx", + "startFrame": 16.0, "endFrame": 16.0, "timeScale": 1.0, "loopFlag": false @@ -2003,146 +1489,66 @@ "children": [] }, { - "id": "TAKEOFFRUN", + "id": "inAirRunApex", "type": "clip", "data": { "url": "qrc:///avatar/animations/jump_running_launch_land.fbx", - "startFrame": 4.0, - "endFrame": 15.0, + "startFrame": 22.0, + "endFrame": 22.0, "timeScale": 1.0, "loopFlag": false }, "children": [] }, { - "id": "inAirStand", - "type": "blendLinear", - "data": { - "alpha": 0.0, - "alphaVar": "inAirAlpha" - }, - "children": [ - { - "id": "inAirStandPreApex", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/jump_standing_apex.fbx", - "startFrame": 0.0, - "endFrame": 0.0, - "timeScale": 1.0, - "loopFlag": false - }, - "children": [] - }, - { - "id": "inAirStandApex", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/jump_standing_apex.fbx", - "startFrame": 1.0, - "endFrame": 1.0, - "timeScale": 1.0, - "loopFlag": false - }, - "children": [] - }, - { - "id": "inAirStandPostApex", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/jump_standing_apex.fbx", - "startFrame": 2.0, - "endFrame": 2.0, - "timeScale": 1.0, - "loopFlag": false - }, - "children": [] - } - ] - }, - { - "id": "INAIRRUN", - "type": "blendLinear", - "data": { - "alpha": 0.0, - "alphaVar": "inAirAlpha" - }, - "children": [ - { - "id": "inAirRunPreApex", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/jump_running_launch_land.fbx", - "startFrame": 16.0, - "endFrame": 16.0, - "timeScale": 1.0, - "loopFlag": false - }, - "children": [] - }, - { - "id": "inAirRunApex", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/jump_running_launch_land.fbx", - "startFrame": 22.0, - "endFrame": 22.0, - "timeScale": 1.0, - "loopFlag": false - }, - "children": [] - }, - { - "id": "inAirRunPostApex", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/jump_running_launch_land.fbx", - "startFrame": 33.0, - "endFrame": 33.0, - "timeScale": 1.0, - "loopFlag": false - }, - "children": [] - } - ] - }, - { - "id": "landStandImpact", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/jump_standing_land_settle.fbx", - "startFrame": 1.0, - "endFrame": 6.0, - "timeScale": 1.0, - "loopFlag": false - }, - "children": [] - }, - { - "id": "landStand", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/jump_standing_land_settle.fbx", - "startFrame": 6.0, - "endFrame": 68.0, - "timeScale": 1.0, - "loopFlag": false - }, - "children": [] - }, - { - "id": "LANDRUN", + "id": "inAirRunPostApex", "type": "clip", "data": { "url": "qrc:///avatar/animations/jump_running_launch_land.fbx", - "startFrame": 29.0, - "endFrame": 40.0, + "startFrame": 33.0, + "endFrame": 33.0, "timeScale": 1.0, "loopFlag": false }, "children": [] } ] + }, + { + "id": "landStandImpact", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jump_standing_land_settle.fbx", + "startFrame": 1.0, + "endFrame": 6.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] + }, + { + "id": "landStand", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jump_standing_land_settle.fbx", + "startFrame": 6.0, + "endFrame": 68.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] + }, + { + "id": "LANDRUN", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jump_running_launch_land.fbx", + "startFrame": 29.0, + "endFrame": 40.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] } ] } diff --git a/interface/resources/avatar/avatar-animation_withIKNode.json b/interface/resources/avatar/avatar-animation_withIKNode.json index 8a66ed21b3..44b2b9c25f 100644 --- a/interface/resources/avatar/avatar-animation_withIKNode.json +++ b/interface/resources/avatar/avatar-animation_withIKNode.json @@ -119,7 +119,7 @@ "type": "poleVectorConstraint", "data": { "enabled": false, - "referenceVector": [ 0, 0, 1 ], + "referenceVector": [ -1, 0, 0 ], "baseJointName": "RightArm", "midJointName": "RightForeArm", "tipJointName": "RightHand", @@ -149,7 +149,7 @@ "type": "poleVectorConstraint", "data": { "enabled": false, - "referenceVector": [ 0, 0, 1 ], + "referenceVector": [ 1, 0, 0 ], "baseJointName": "LeftArm", "midJointName": "LeftForeArm", "tipJointName": "LeftHand", diff --git a/libraries/animation/src/AnimInverseKinematics.cpp b/libraries/animation/src/AnimInverseKinematics.cpp index 7a29ff4001..8c365d2561 100644 --- a/libraries/animation/src/AnimInverseKinematics.cpp +++ b/libraries/animation/src/AnimInverseKinematics.cpp @@ -886,8 +886,7 @@ const AnimPoseVec& AnimInverseKinematics::overlay(const AnimVariantMap& animVars if (dt > MAX_OVERLAY_DT) { dt = MAX_OVERLAY_DT; } - loadPoses(underPoses); - /* + if (_relativePoses.size() != underPoses.size()) { loadPoses(underPoses); } else { @@ -974,8 +973,8 @@ const AnimPoseVec& AnimInverseKinematics::overlay(const AnimVariantMap& animVars ::blend(1, &prevHipsAbsPose, &absPose, alpha, &absPose); } - //_relativePoses[_hipsIndex] = parentAbsPose.inverse() * absPose; - //_relativePoses[_hipsIndex].scale() = glm::vec3(1.0f); + _relativePoses[_hipsIndex] = parentAbsPose.inverse() * absPose; + _relativePoses[_hipsIndex].scale() = glm::vec3(1.0f); } // if there is an active jointChainInfo for the hips store the post shifted hips into it. @@ -1043,7 +1042,7 @@ const AnimPoseVec& AnimInverseKinematics::overlay(const AnimVariantMap& animVars preconditionRelativePosesToAvoidLimbLock(context, targets); //qCDebug(animation) << "hips before ccd" << _relativePoses[_hipsIndex]; - //solve(context, targets, dt, jointChainInfoVec); + solve(context, targets, dt, jointChainInfoVec); //qCDebug(animation) << "hips after ccd" << _relativePoses[_hipsIndex]; } @@ -1055,7 +1054,7 @@ const AnimPoseVec& AnimInverseKinematics::overlay(const AnimVariantMap& animVars } processOutputJoints(triggersOut); - */ + return _relativePoses; } diff --git a/libraries/animation/src/AnimSplineIK.cpp b/libraries/animation/src/AnimSplineIK.cpp index 847d512a51..39f8767465 100644 --- a/libraries/animation/src/AnimSplineIK.cpp +++ b/libraries/animation/src/AnimSplineIK.cpp @@ -71,133 +71,71 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const } ////////////////////////////////////////////////////////////////////////////////// - // check to see if we actually need absolute poses. AnimPoseVec absolutePoses; absolutePoses.resize(_poses.size()); computeAbsolutePoses(absolutePoses); - AnimPoseVec absolutePoses2; - absolutePoses2.resize(_poses.size()); - // do this later - //computeAbsolutePoses(absolutePoses2); - - int jointIndex2 = _skeleton->nameToJointIndex("Spine2"); - AnimPose origSpine2PoseAbs = _skeleton->getAbsolutePose(jointIndex2, _poses); - if ((jointIndex2 != -1) && (_poses.size() > 0)) { - AnimPose origSpine2 = _skeleton->getAbsolutePose(jointIndex2, _poses); - AnimPose origSpine1 = _skeleton->getAbsolutePose(_skeleton->nameToJointIndex("Spine1"),_poses); - //origSpine2PoseRel = origSpine1.inverse() * origSpine2; - //qCDebug(animation) << "origSpine2Pose: " << origSpine2Pose.rot(); - //qCDebug(animation) << "original relative spine2 " << origSpine2PoseAbs; - } - - IKTarget target; - int jointIndex = _skeleton->nameToJointIndex("Head"); - if (jointIndex != -1) { + if (_headIndex != -1) { target.setType(animVars.lookup("headType", (int)IKTarget::Type::RotationAndPosition)); - target.setIndex(jointIndex); - AnimPose absPose = _skeleton->getAbsolutePose(jointIndex, _poses); + target.setIndex(_headIndex); + AnimPose absPose = _skeleton->getAbsolutePose(_headIndex, _poses); glm::quat rotation = animVars.lookupRigToGeometry("headRotation", absPose.rot()); glm::vec3 translation = animVars.lookupRigToGeometry("headPosition", absPose.trans()); float weight = animVars.lookup("headWeight", "4.0"); - //qCDebug(animation) << "target 1 rotation absolute" << rotation; target.setPose(rotation, translation); target.setWeight(weight); - //const float* flexCoefficients = new float[5]{ 1.0f, 0.5f, 0.25f, 0.2f, 0.1f }; - const float* flexCoefficients = new float[2]{ 1.0f, 0.5f }; - target.setFlexCoefficients(2, flexCoefficients); - - // record the index of the hips ik target. - if (target.getIndex() == _hipsIndex) { - _hipsTargetIndex = 1; - } + const float* flexCoefficients = new float[5]{ 1.0f, 1.0f, 1.0f, 1.0f, 1.0f }; + //const float* flexCoefficients = new float[2]{ 0.0f, 1.0f }; + target.setFlexCoefficients(5, flexCoefficients); } - AnimPose origAbsAfterHeadSpline; - AnimPose finalSpine2; AnimChain jointChain; AnimPose targetSpine2; + AnimPoseVec absolutePoses2; + absolutePoses2.resize(_poses.size()); if (_poses.size() > 0) { - _snapshotChain.buildFromRelativePoses(_skeleton, _poses, target.getIndex()); + //_snapshotChain.buildFromRelativePoses(_skeleton, _poses, target.getIndex()); jointChain.buildFromRelativePoses(_skeleton, _poses, target.getIndex()); - // jointChain2.buildFromRelativePoses(_skeleton, _poses, target2.getIndex()); - - // for each target solve target with spline - //qCDebug(animation) << "before head spline"; - //jointChain.dump(); solveTargetWithSpline(context, target, absolutePoses, false, jointChain); - AnimPose afterSolveSpine2 = jointChain.getAbsolutePoseFromJointIndex(jointIndex2); - AnimPose afterSolveSpine1 = jointChain.getAbsolutePoseFromJointIndex(_skeleton->nameToJointIndex("Spine1")); - AnimPose afterSolveSpine2Rel = afterSolveSpine1.inverse() * afterSolveSpine2; - AnimPose originalSpine2Relative = afterSolveSpine1.inverse() * origSpine2PoseAbs; - glm::quat rotation3 = animVars.lookupRigToGeometry("spine2Rotation", afterSolveSpine2.rot()); - glm::vec3 translation3 = animVars.lookupRigToGeometry("spine2Position", afterSolveSpine2.trans()); - targetSpine2 = AnimPose(rotation3, afterSolveSpine2.trans()); - finalSpine2 = afterSolveSpine1.inverse() * targetSpine2; - - //qCDebug(animation) << "relative spine2 after solve" << afterSolveSpine2Rel; - //qCDebug(animation) << "relative spine2 orig" << originalSpine2Relative; - AnimPose latestSpine2Relative(originalSpine2Relative.rot(), afterSolveSpine2Rel.trans()); - //jointChain.setRelativePoseAtJointIndex(jointIndex2, finalSpine2); jointChain.outputRelativePoses(_poses); - //_poses[_headIndex] = jointChain.getRelativePoseAtJointIndex(_headIndex); - //_poses[_skeleton->nameToJointIndex("Neck")] = jointChain.getRelativePoseAtJointIndex(_skeleton->nameToJointIndex("Neck")); - //_poses[_spine2Index] = jointChain.getRelativePoseAtJointIndex(_spine2Index); - - //custom output code for the head. just do the head neck and spine2 - - //qCDebug(animation) << "after head spline"; - //jointChain.dump(); - - computeAbsolutePoses(absolutePoses2); - //origAbsAfterHeadSpline = _skeleton->getAbsolutePose(jointIndex2, _poses); - // qCDebug(animation) << "Spine2 trans after head spline: " << origAbsAfterHeadSpline.trans(); + AnimPose afterSolveSpine2 = _skeleton->getAbsolutePose(_spine2Index, _poses); + glm::quat spine2RotationTarget = animVars.lookupRigToGeometry("spine2Rotation", afterSolveSpine2.rot()); + targetSpine2 = AnimPose(spine2RotationTarget, afterSolveSpine2.trans()); } + /* IKTarget target2; - //int jointIndex2 = _skeleton->nameToJointIndex("Spine2"); - if (jointIndex2 != -1) { + computeAbsolutePoses(absolutePoses2); + if (_spine2Index != -1) { target2.setType(animVars.lookup("spine2Type", (int)IKTarget::Type::RotationAndPosition)); - target2.setIndex(jointIndex2); - AnimPose absPose2 = _skeleton->getAbsolutePose(jointIndex2, _poses); - glm::quat rotation2 = animVars.lookupRigToGeometry("spine2Rotation", absPose2.rot()); - glm::vec3 translation2 = animVars.lookupRigToGeometry("spine2Position", absPose2.trans()); - float weight2 = animVars.lookup("spine2Weight", "2.0"); - // qCDebug(animation) << "rig to geometry" << rotation2; + target2.setIndex(_spine2Index); - //target2.setPose(rotation2, translation2); + float weight2 = animVars.lookup("spine2Weight", "2.0"); + target2.setPose(targetSpine2.rot(), targetSpine2.trans()); target2.setWeight(weight2); - const float* flexCoefficients2 = new float[3]{ 1.0f, 0.5f, 0.25f }; + + const float* flexCoefficients2 = new float[3]{ 1.0f, 1.0f, 1.0f }; target2.setFlexCoefficients(3, flexCoefficients2); - - } + AnimChain jointChain2; + AnimPose beforeSolveChestNeck; if (_poses.size() > 0) { - // _snapshotChain.buildFromRelativePoses(_skeleton, _poses, target.getIndex()); - // jointChain.buildFromRelativePoses(_skeleton, _poses, target.getIndex()); - // jointChain2.buildFromRelativePoses(_skeleton, underPoses, target2.getIndex()); + + beforeSolveChestNeck = _skeleton->getAbsolutePose(_skeleton->nameToJointIndex("Neck"), _poses); + jointChain2.buildFromRelativePoses(_skeleton, _poses, target2.getIndex()); - - // for each target solve target with spline solveTargetWithSpline(context, target2, absolutePoses2, false, jointChain2); - - //jointChain.outputRelativePoses(_poses); jointChain2.outputRelativePoses(_poses); - //computeAbsolutePoses(absolutePoses); - //qCDebug(animation) << "Spine2 spline"; - //jointChain2.dump(); - //qCDebug(animation) << "Spine2Pose trans after spine2 spline: " << _skeleton->getAbsolutePose(jointIndex2, _poses).trans(); - } - + */ const float FRAMES_PER_SECOND = 30.0f; @@ -209,9 +147,26 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const // make the prevchain // interp from the previous chain to the new chain/or underposes if the ik is disabled. // update the relative poses and then we are done - - /**/ + // set the tip/head rotation to match the absolute rotation of the target. + int headParent = _skeleton->getParentIndex(_headIndex); + int spine2Parent = _skeleton->getParentIndex(_spine2Index); + if ((spine2Parent != -1) && (headParent != -1) && (_poses.size() > 0)) { + /* + AnimPose spine2Target(target2.getRotation(), target2.getTranslation()); + AnimPose finalSpine2RelativePose = _skeleton->getAbsolutePose(spine2Parent, _poses).inverse() * spine2Target; + _poses[_spine2Index] = finalSpine2RelativePose; + + + AnimPose neckAbsolute = _skeleton->getAbsolutePose(headParent, _poses); + AnimPose finalNeckAbsolute = AnimPose(safeLerp(target2.getRotation(), target.getRotation(), 1.0f),neckAbsolute.trans()); + _poses[headParent] = spine2Target.inverse() * beforeSolveChestNeck; + */ + AnimPose headTarget(target.getRotation(),target.getTranslation()); + AnimPose finalHeadRelativePose = _skeleton->getAbsolutePose(headParent,_poses).inverse() * headTarget; + _poses[_headIndex] = finalHeadRelativePose; + } + return _poses; } @@ -275,19 +230,19 @@ void AnimSplineIK::solveTargetWithSpline(const AnimContext& context, const IKTar // build spline from tip to base AnimPose tipPose = AnimPose(glm::vec3(1.0f), target.getRotation(), target.getTranslation()); AnimPose basePose; - if (target.getIndex() == _headIndex) { - basePose = absolutePoses[headBaseIndex]; - } else { + //if (target.getIndex() == _headIndex) { + // basePose = absolutePoses[headBaseIndex]; + //} else { basePose = absolutePoses[baseIndex]; - } + //} CubicHermiteSplineFunctorWithArcLength spline; if (target.getIndex() == _headIndex) { // set gain factors so that more curvature occurs near the tip of the spline. const float HIPS_GAIN = 0.5f; const float HEAD_GAIN = 1.0f; - //spline = computeSplineFromTipAndBase(tipPose, basePose, HIPS_GAIN, HEAD_GAIN); - spline = computeSplineFromTipAndBase(tipPose, basePose); + spline = computeSplineFromTipAndBase(tipPose, basePose, HIPS_GAIN, HEAD_GAIN); + // spline = computeSplineFromTipAndBase(tipPose, basePose); } else { spline = computeSplineFromTipAndBase(tipPose, basePose); } @@ -359,6 +314,9 @@ void AnimSplineIK::solveTargetWithSpline(const AnimContext& context, const IKTar if (!chainInfoOut.setRelativePoseAtJointIndex(splineJointInfo.jointIndex, relPose)) { qCDebug(animation) << "we didn't find the joint index for the spline!!!!"; } + if (splineJointInfo.jointIndex == _skeleton->nameToJointIndex("Neck")) { + qCDebug(animation) << "neck is " << relPose; + } parentAbsPose = flexedAbsPose; } @@ -393,8 +351,8 @@ void AnimSplineIK::computeAndCacheSplineJointInfosForIKTarget(const AnimContext& AnimPose tipPose = _skeleton->getAbsoluteDefaultPose(target.getIndex()); AnimPose basePose; if (target.getIndex() == _headIndex) { - //basePose = _skeleton->getAbsoluteDefaultPose(_hipsIndex); - basePose = _skeleton->getAbsoluteDefaultPose(_spine2Index); + basePose = _skeleton->getAbsoluteDefaultPose(_hipsIndex); + //basePose = _skeleton->getAbsoluteDefaultPose(_spine2Index); } else { basePose = _skeleton->getAbsoluteDefaultPose(_hipsIndex); } @@ -404,8 +362,8 @@ void AnimSplineIK::computeAndCacheSplineJointInfosForIKTarget(const AnimContext& // set gain factors so that more curvature occurs near the tip of the spline. const float HIPS_GAIN = 0.5f; const float HEAD_GAIN = 1.0f; - // spline = computeSplineFromTipAndBase(tipPose, basePose, HIPS_GAIN, HEAD_GAIN); - spline = computeSplineFromTipAndBase(tipPose, basePose); + spline = computeSplineFromTipAndBase(tipPose, basePose, HIPS_GAIN, HEAD_GAIN); + // spline = computeSplineFromTipAndBase(tipPose, basePose); } else { spline = computeSplineFromTipAndBase(tipPose, basePose); } diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index a34af09b27..70f1f9a1f7 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -1544,6 +1544,7 @@ void Rig::updateHands2(bool leftHandEnabled, bool rightHandEnabled, bool headEna int oppositeArmJointIndex = _animSkeleton->nameToJointIndex("RightArm"); glm::vec3 poleVector; bool usePoleVector = calculateElbowPoleVector(handJointIndex, elbowJointIndex, shoulderJointIndex, oppositeArmJointIndex, poleVector); + //glm::vec3 poleVector = calculateKneePoleVector(handJointIndex, elbowJointIndex, shoulderJointIndex, hipsIndex, rightHandPose); glm::vec3 sensorPoleVector = transformVectorFast(rigToSensorMatrix, poleVector); // smooth toward desired pole vector from previous pole vector... to reduce jitter, but in sensor space. @@ -1556,7 +1557,7 @@ void Rig::updateHands2(bool leftHandEnabled, bool rightHandEnabled, bool headEna _prevLeftHandPoleVector = smoothDeltaRot * _prevLeftHandPoleVector; _animVars.set("leftHandPoleVectorEnabled", true); - _animVars.set("leftHandPoleVector", transformVectorFast(sensorToRigMatrix, _prevLeftFootPoleVector)); + _animVars.set("leftHandPoleVector", transformVectorFast(sensorToRigMatrix, _prevLeftHandPoleVector)); } else { // We want to drive the IK from the underlying animation. // This gives us the ability to squat while in the HMD, without the feet from dipping under the floor. @@ -1595,7 +1596,7 @@ void Rig::updateHands2(bool leftHandEnabled, bool rightHandEnabled, bool headEna _prevRightHandPoleVector = smoothDeltaRot * _prevRightHandPoleVector; _animVars.set("rightHandPoleVectorEnabled", true); - _animVars.set("rightHandPoleVector", transformVectorFast(sensorToRigMatrix, _prevRightFootPoleVector)); + _animVars.set("rightHandPoleVector", transformVectorFast(sensorToRigMatrix, _prevRightHandPoleVector)); } else { // We want to drive the IK from the underlying animation. // This gives us the ability to squat while in the HMD, without the feet from dipping under the floor. @@ -1856,14 +1857,14 @@ void Rig::updateFromControllerParameters(const ControllerParameters& params, flo updateHead(_headEnabled, hipsEnabled, params.primaryControllerPoses[PrimaryControllerType_Head]); - //updateHands(leftHandEnabled, rightHandEnabled, hipsEnabled, hipsEstimated, leftArmEnabled, rightArmEnabled, _headEnabled, dt, - // params.primaryControllerPoses[PrimaryControllerType_LeftHand], params.primaryControllerPoses[PrimaryControllerType_RightHand], - // params.hipsShapeInfo, params.spineShapeInfo, params.spine1ShapeInfo, params.spine2ShapeInfo, - // params.rigToSensorMatrix, sensorToRigMatrix); + updateHands(leftHandEnabled, rightHandEnabled, hipsEnabled, hipsEstimated, leftArmEnabled, rightArmEnabled, _headEnabled, dt, + params.primaryControllerPoses[PrimaryControllerType_LeftHand], params.primaryControllerPoses[PrimaryControllerType_RightHand], + params.hipsShapeInfo, params.spineShapeInfo, params.spine1ShapeInfo, params.spine2ShapeInfo, + params.rigToSensorMatrix, sensorToRigMatrix); - updateHands2(leftHandEnabled, rightHandEnabled, _headEnabled, - params.primaryControllerPoses[PrimaryControllerType_LeftHand], params.primaryControllerPoses[PrimaryControllerType_RightHand], - params.rigToSensorMatrix, sensorToRigMatrix); + //updateHands2(leftHandEnabled, rightHandEnabled, _headEnabled, + // params.primaryControllerPoses[PrimaryControllerType_LeftHand], params.primaryControllerPoses[PrimaryControllerType_RightHand], + // params.rigToSensorMatrix, sensorToRigMatrix); updateFeet(leftFootEnabled, rightFootEnabled, _headEnabled, params.primaryControllerPoses[PrimaryControllerType_LeftFoot], params.primaryControllerPoses[PrimaryControllerType_RightFoot], From 37f92d2319b3a09148706ffb1987c3f4715a0c48 Mon Sep 17 00:00:00 2001 From: amantley Date: Thu, 24 Jan 2019 17:02:30 -0800 Subject: [PATCH 014/112] added code to read tip and base var info from the json --- .../avatar/avatar-animation_withIKNode.json | 7 + .../animation/src/AnimInverseKinematics.cpp | 15 +- libraries/animation/src/AnimNodeLoader.cpp | 12 +- libraries/animation/src/AnimSplineIK.cpp | 208 ++++++++++++------ libraries/animation/src/AnimSplineIK.h | 20 +- libraries/animation/src/Rig.cpp | 14 +- 6 files changed, 194 insertions(+), 82 deletions(-) diff --git a/interface/resources/avatar/avatar-animation_withIKNode.json b/interface/resources/avatar/avatar-animation_withIKNode.json index 44b2b9c25f..04ed593755 100644 --- a/interface/resources/avatar/avatar-animation_withIKNode.json +++ b/interface/resources/avatar/avatar-animation_withIKNode.json @@ -183,6 +183,13 @@ "interpDuration": 15, "baseJointName": "Hips", "tipJointName": "Head", + "secondaryTargetJointName": "Spine2", + "basePositionVar": "hipsPosition", + "baseRotationVar": "hipsRotation", + "tipPositionVar": "headPosition", + "tipRotationVar": "headRotation", + "secondaryTargetPositionVar": "spine2Position", + "secondaryTargetRotationVar": "spine2Rotation", "alphaVar": "splineIKAlpha", "enabledVar": "splineIKEnabled", "endEffectorRotationVarVar": "splineIKRotationVar", diff --git a/libraries/animation/src/AnimInverseKinematics.cpp b/libraries/animation/src/AnimInverseKinematics.cpp index 8c365d2561..f95fe3333f 100644 --- a/libraries/animation/src/AnimInverseKinematics.cpp +++ b/libraries/animation/src/AnimInverseKinematics.cpp @@ -243,13 +243,6 @@ void AnimInverseKinematics::solve(const AnimContext& context, const std::vector< break; case IKTarget::Type::Spline: solveTargetWithSpline(context, targets[i], absolutePoses, debug, jointChainInfoVec[i]); - //if (jointChainInfoVec[i].target.getIndex() == _skeleton->nameToJointIndex("Head")) { - // qCDebug(animation) << "AnimIK spline index is " << targets[i].getIndex() << " and chain info size is " << jointChainInfoVec[i].jointInfoVec.size(); - for (int w = 0; w < jointChainInfoVec[i].jointInfoVec.size(); w++) { - // qCDebug(animation) << "joint " << jointChainInfoVec[i].jointInfoVec[w].jointIndex << " rotation is " << jointChainInfoVec[i].jointInfoVec[w].rot; - // qCDebug(animation) << "joint " << jointChainInfoVec[i].jointInfoVec[w].jointIndex << " translation is " << jointChainInfoVec[i].jointInfoVec[w].trans; - } - //} break; default: solveTargetWithCCD(context, targets[i], absolutePoses, debug, jointChainInfoVec[i]); @@ -329,6 +322,10 @@ void AnimInverseKinematics::solve(const AnimContext& context, const std::vector< } } + //qCDebug(animation) << "joint chain pose for head animIK " << jointChainInfoVec[4].jointInfoVec[w].trans << " " << jointChainInfoVec[4].jointInfoVec[w].rot; + qCDebug(animation) << "absolute pose for head animIK " << absolutePoses[_skeleton->nameToJointIndex("Head")]; + qCDebug(animation) << "target pose for head animIK " << targets[4].getTranslation() << " " << targets[4].getRotation(); + // compute maxError maxError = 0.0f; for (size_t i = 0; i < targets.size(); i++) { @@ -833,7 +830,9 @@ void AnimInverseKinematics::solveTargetWithSpline(const AnimContext& context, co AnimPose relPose = parentAbsPose.inverse() * flexedAbsPose; + bool constrained = false; + /* if (splineJointInfo.jointIndex != _hipsIndex) { // constrain the amount the spine can stretch or compress float length = glm::length(relPose.trans()); @@ -854,7 +853,7 @@ void AnimInverseKinematics::solveTargetWithSpline(const AnimContext& context, co relPose.trans() = glm::vec3(0.0f); } } - + */ jointChainInfoOut.jointInfoVec[i] = { relPose.rot(), relPose.trans(), splineJointInfo.jointIndex, constrained }; parentAbsPose = flexedAbsPose; diff --git a/libraries/animation/src/AnimNodeLoader.cpp b/libraries/animation/src/AnimNodeLoader.cpp index ec9099df8b..ebe9dbe3ba 100644 --- a/libraries/animation/src/AnimNodeLoader.cpp +++ b/libraries/animation/src/AnimNodeLoader.cpp @@ -585,6 +585,13 @@ static AnimNode::Pointer loadSplineIKNode(const QJsonObject& jsonObj, const QStr READ_FLOAT(interpDuration, jsonObj, id, jsonUrl, nullptr); READ_STRING(baseJointName, jsonObj, id, jsonUrl, nullptr); READ_STRING(tipJointName, jsonObj, id, jsonUrl, nullptr); + READ_STRING(secondaryTargetJointName, jsonObj, id, jsonUrl, nullptr); + READ_STRING(basePositionVar, jsonObj, id, jsonUrl, nullptr); + READ_STRING(baseRotationVar, jsonObj, id, jsonUrl, nullptr); + READ_STRING(tipPositionVar, jsonObj, id, jsonUrl, nullptr); + READ_STRING(tipRotationVar, jsonObj, id, jsonUrl, nullptr); + READ_STRING(secondaryTargetPositionVar, jsonObj, id, jsonUrl, nullptr); + READ_STRING(secondaryTargetRotationVar, jsonObj, id, jsonUrl, nullptr); READ_STRING(alphaVar, jsonObj, id, jsonUrl, nullptr); READ_STRING(enabledVar, jsonObj, id, jsonUrl, nullptr); READ_STRING(endEffectorRotationVarVar, jsonObj, id, jsonUrl, nullptr); @@ -592,8 +599,9 @@ static AnimNode::Pointer loadSplineIKNode(const QJsonObject& jsonObj, const QStr auto node = std::make_shared(id, alpha, enabled, interpDuration, baseJointName, tipJointName, - alphaVar, enabledVar, - endEffectorRotationVarVar, endEffectorPositionVarVar); + alphaVar, enabledVar, endEffectorRotationVarVar, endEffectorPositionVarVar, + basePositionVar, baseRotationVar, + tipPositionVar, tipRotationVar, secondaryTargetJointName, secondaryTargetPositionVar, secondaryTargetRotationVar); return node; } diff --git a/libraries/animation/src/AnimSplineIK.cpp b/libraries/animation/src/AnimSplineIK.cpp index 39f8767465..afe9f6dfcb 100644 --- a/libraries/animation/src/AnimSplineIK.cpp +++ b/libraries/animation/src/AnimSplineIK.cpp @@ -20,7 +20,14 @@ AnimSplineIK::AnimSplineIK(const QString& id, float alpha, bool enabled, float i const QString& baseJointName, const QString& tipJointName, const QString& alphaVar, const QString& enabledVar, - const QString& endEffectorRotationVarVar, const QString& endEffectorPositionVarVar) : + const QString& endEffectorRotationVarVar, const QString& endEffectorPositionVarVar, + const QString& basePositionVar, + const QString& baseRotationVar, + const QString& tipPositionVar, + const QString& tipRotationVar, + const QString& secondaryTargetJointName, + const QString& secondaryTargetPositionVar, + const QString& secondaryTargetRotationVar) : AnimNode(AnimNode::Type::SplineIK, id), _alpha(alpha), _enabled(enabled), @@ -32,7 +39,15 @@ AnimSplineIK::AnimSplineIK(const QString& id, float alpha, bool enabled, float i _endEffectorRotationVarVar(endEffectorRotationVarVar), _endEffectorPositionVarVar(endEffectorPositionVarVar), _prevEndEffectorRotationVar(), - _prevEndEffectorPositionVar() { + _prevEndEffectorPositionVar(), + _basePositionVar(basePositionVar), + _baseRotationVar(baseRotationVar), + _tipPositionVar(tipPositionVar), + _tipRotationVar(tipRotationVar), + _secondaryTargetJointName(secondaryTargetJointName), + _secondaryTargetPositionVar(secondaryTargetPositionVar), + _secondaryTargetRotationVar(secondaryTargetRotationVar) +{ } @@ -51,16 +66,19 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const if (_children.size() != 1) { return _poses; } - // evalute underPoses + // evaluate underPoses AnimPoseVec underPoses = _children[0]->evaluate(animVars, context, dt, triggersOut); _poses = underPoses; - // now we override the hips relative pose based on the hips target that has been set. + glm::quat hipsTargetRotation; + glm::vec3 hipsTargetTranslation; + + // now we override the hips with the hips target pose. //////////////////////////////////////////////////// if (_poses.size() > 0) { AnimPose hipsUnderPose = _skeleton->getAbsolutePose(_hipsIndex, _poses); - glm::quat hipsTargetRotation = animVars.lookupRigToGeometry("hipsRotation", hipsUnderPose.rot()); - glm::vec3 hipsTargetTranslation = animVars.lookupRigToGeometry("hipsPosition", hipsUnderPose.trans()); + hipsTargetRotation = animVars.lookupRigToGeometry("hipsRotation", hipsUnderPose.rot()); + hipsTargetTranslation = animVars.lookupRigToGeometry("hipsPosition", hipsUnderPose.trans()); AnimPose absHipsTargetPose(hipsTargetRotation, hipsTargetTranslation); int hipsParentIndex = _skeleton->getParentIndex(_hipsIndex); @@ -76,23 +94,22 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const computeAbsolutePoses(absolutePoses); IKTarget target; - if (_headIndex != -1) { - target.setType(animVars.lookup("headType", (int)IKTarget::Type::RotationAndPosition)); - target.setIndex(_headIndex); - AnimPose absPose = _skeleton->getAbsolutePose(_headIndex, _poses); - glm::quat rotation = animVars.lookupRigToGeometry("headRotation", absPose.rot()); - glm::vec3 translation = animVars.lookupRigToGeometry("headPosition", absPose.trans()); - float weight = animVars.lookup("headWeight", "4.0"); + if (_tipJointIndex != -1) { + target.setType((int)IKTarget::Type::Spline); + target.setIndex(_tipJointIndex); + AnimPose absPose = _skeleton->getAbsolutePose(_tipJointIndex, _poses); + glm::quat rotation = animVars.lookupRigToGeometry(_tipRotationVar, absPose.rot()); + glm::vec3 translation = animVars.lookupRigToGeometry(_tipPositionVar, absPose.trans()); + float weight = 1.0f; target.setPose(rotation, translation); target.setWeight(weight); - const float* flexCoefficients = new float[5]{ 1.0f, 1.0f, 1.0f, 1.0f, 1.0f }; - //const float* flexCoefficients = new float[2]{ 0.0f, 1.0f }; + const float* flexCoefficients = new float[5]{ 1.0f, 0.5f, 0.25f, 0.2f, 0.1f }; target.setFlexCoefficients(5, flexCoefficients); } AnimChain jointChain; - AnimPose targetSpine2; + AnimPose updatedSecondaryTarget; AnimPoseVec absolutePoses2; absolutePoses2.resize(_poses.size()); if (_poses.size() > 0) { @@ -100,43 +117,47 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const //_snapshotChain.buildFromRelativePoses(_skeleton, _poses, target.getIndex()); jointChain.buildFromRelativePoses(_skeleton, _poses, target.getIndex()); solveTargetWithSpline(context, target, absolutePoses, false, jointChain); + jointChain.buildDirtyAbsolutePoses(); + qCDebug(animation) << "the jointChain Result for head " << jointChain.getAbsolutePoseFromJointIndex(_tipJointIndex); + qCDebug(animation) << "the orig target pose for head " << target.getPose(); jointChain.outputRelativePoses(_poses); - AnimPose afterSolveSpine2 = _skeleton->getAbsolutePose(_spine2Index, _poses); - glm::quat spine2RotationTarget = animVars.lookupRigToGeometry("spine2Rotation", afterSolveSpine2.rot()); + AnimPose afterSolveSecondaryTarget = _skeleton->getAbsolutePose(_secondaryTargetIndex, _poses); + glm::quat secondaryTargetRotation = animVars.lookupRigToGeometry(_secondaryTargetRotationVar, afterSolveSecondaryTarget.rot()); - targetSpine2 = AnimPose(spine2RotationTarget, afterSolveSpine2.trans()); + // updatedSecondaryTarget = AnimPose(secondaryTargetRotation, afterSolveSpine2.trans()); + updatedSecondaryTarget = AnimPose(afterSolveSecondaryTarget.rot(), afterSolveSecondaryTarget.trans()); } - /* - IKTarget target2; + + IKTarget secondaryTarget; computeAbsolutePoses(absolutePoses2); - if (_spine2Index != -1) { - target2.setType(animVars.lookup("spine2Type", (int)IKTarget::Type::RotationAndPosition)); - target2.setIndex(_spine2Index); + if (_secondaryTargetIndex != -1) { + secondaryTarget.setType((int)IKTarget::Type::Spline); + secondaryTarget.setIndex(_secondaryTargetIndex); - float weight2 = animVars.lookup("spine2Weight", "2.0"); + float weight2 = 1.0f; - target2.setPose(targetSpine2.rot(), targetSpine2.trans()); - target2.setWeight(weight2); + secondaryTarget.setPose(updatedSecondaryTarget.rot(), updatedSecondaryTarget.trans()); + secondaryTarget.setWeight(weight2); const float* flexCoefficients2 = new float[3]{ 1.0f, 1.0f, 1.0f }; - target2.setFlexCoefficients(3, flexCoefficients2); + secondaryTarget.setFlexCoefficients(3, flexCoefficients2); } - - AnimChain jointChain2; + /* + AnimChain secondaryJointChain; AnimPose beforeSolveChestNeck; if (_poses.size() > 0) { beforeSolveChestNeck = _skeleton->getAbsolutePose(_skeleton->nameToJointIndex("Neck"), _poses); - jointChain2.buildFromRelativePoses(_skeleton, _poses, target2.getIndex()); - solveTargetWithSpline(context, target2, absolutePoses2, false, jointChain2); - jointChain2.outputRelativePoses(_poses); + secondaryJointChain.buildFromRelativePoses(_skeleton, _poses, secondaryTarget.getIndex()); + solveTargetWithSpline(context, secondaryTarget, absolutePoses2, false, secondaryJointChain); + secondaryJointChain.outputRelativePoses(_poses); } - */ + */ const float FRAMES_PER_SECOND = 30.0f; _interpAlphaVel = FRAMES_PER_SECOND / _interpDuration; @@ -149,23 +170,59 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const // update the relative poses and then we are done // set the tip/head rotation to match the absolute rotation of the target. - int headParent = _skeleton->getParentIndex(_headIndex); - int spine2Parent = _skeleton->getParentIndex(_spine2Index); - if ((spine2Parent != -1) && (headParent != -1) && (_poses.size() > 0)) { + int tipParent = _skeleton->getParentIndex(_tipJointIndex); + int secondaryTargetParent = _skeleton->getParentIndex(_secondaryTargetIndex); + if ((secondaryTargetParent != -1) && (tipParent != -1) && (_poses.size() > 0)) { /* - AnimPose spine2Target(target2.getRotation(), target2.getTranslation()); - AnimPose finalSpine2RelativePose = _skeleton->getAbsolutePose(spine2Parent, _poses).inverse() * spine2Target; - _poses[_spine2Index] = finalSpine2RelativePose; + AnimPose secondaryTargetPose(target2.getRotation(), target2.getTranslation()); + AnimPose secondaryTargetRelativePose = _skeleton->getAbsolutePose(secondaryTargetParent, _poses).inverse() * secondaryTargetPose; + _poses[_secondaryTargetIndex] = secondaryTargetRelativePose; - AnimPose neckAbsolute = _skeleton->getAbsolutePose(headParent, _poses); + AnimPose neckAbsolute = _skeleton->getAbsolutePose(tipParent, _poses); AnimPose finalNeckAbsolute = AnimPose(safeLerp(target2.getRotation(), target.getRotation(), 1.0f),neckAbsolute.trans()); _poses[headParent] = spine2Target.inverse() * beforeSolveChestNeck; */ - AnimPose headTarget(target.getRotation(),target.getTranslation()); - AnimPose finalHeadRelativePose = _skeleton->getAbsolutePose(headParent,_poses).inverse() * headTarget; - _poses[_headIndex] = finalHeadRelativePose; + //AnimPose tipTarget(target.getRotation(),target.getTranslation()); + //AnimPose tipRelativePose = _skeleton->getAbsolutePose(tipParent,_poses).inverse() * headTarget; + //_poses[_tipJointIndex] = tipHeadRelativePose; } + + // debug render ik targets + if (context.getEnableDebugDrawIKTargets()) { + const vec4 WHITE(1.0f); + const vec4 GREEN(0.0f, 1.0f, 0.0f, 1.0f); + glm::mat4 rigToAvatarMat = createMatFromQuatAndPos(Quaternions::Y_180, glm::vec3()); + + glm::mat4 geomTargetMat = createMatFromQuatAndPos(target.getRotation(), target.getTranslation()); + glm::mat4 avatarTargetMat = rigToAvatarMat * context.getGeometryToRigMatrix() * geomTargetMat; + QString name = QString("ikTargetHead"); + DebugDraw::getInstance().addMyAvatarMarker(name, glmExtractRotation(avatarTargetMat), extractTranslation(avatarTargetMat), WHITE); + + glm::mat4 geomTargetMat2 = createMatFromQuatAndPos(secondaryTarget.getRotation(), secondaryTarget.getTranslation()); + glm::mat4 avatarTargetMat2 = rigToAvatarMat * context.getGeometryToRigMatrix() * geomTargetMat2; + QString name2 = QString("ikTargetSpine2"); + DebugDraw::getInstance().addMyAvatarMarker(name2, glmExtractRotation(avatarTargetMat2), extractTranslation(avatarTargetMat2), WHITE); + + + glm::mat4 geomTargetMat3 = createMatFromQuatAndPos(hipsTargetRotation, hipsTargetTranslation); + glm::mat4 avatarTargetMat3 = rigToAvatarMat * context.getGeometryToRigMatrix() * geomTargetMat3; + QString name3 = QString("ikTargetHips"); + DebugDraw::getInstance().addMyAvatarMarker(name3, glmExtractRotation(avatarTargetMat3), extractTranslation(avatarTargetMat3), WHITE); + + + } else if (context.getEnableDebugDrawIKTargets() != _previousEnableDebugIKTargets) { + // remove markers if they were added last frame. + + QString name = QString("ikTargetHead"); + DebugDraw::getInstance().removeMyAvatarMarker(name); + QString name2 = QString("ikTargetSpine2"); + DebugDraw::getInstance().removeMyAvatarMarker(name2); + QString name3 = QString("ikTargetHips"); + DebugDraw::getInstance().removeMyAvatarMarker(name3); + + } + _previousEnableDebugIKTargets = context.getEnableDebugDrawIKTargets(); return _poses; } @@ -174,11 +231,12 @@ void AnimSplineIK::lookUpIndices() { assert(_skeleton); // look up bone indices by name - std::vector indices = _skeleton->lookUpJointIndices({ _baseJointName, _tipJointName }); + std::vector indices = _skeleton->lookUpJointIndices({ _baseJointName, _tipJointName, _secondaryTargetJointName }); // cache the results _baseJointIndex = indices[0]; _tipJointIndex = indices[1]; + _secondaryTargetIndex = indices[2]; if (_baseJointIndex != -1) { _baseParentJointIndex = _skeleton->getParentIndex(_baseJointIndex); @@ -206,9 +264,8 @@ const AnimPoseVec& AnimSplineIK::getPosesInternal() const { void AnimSplineIK::setSkeletonInternal(AnimSkeleton::ConstPointer skeleton) { AnimNode::setSkeletonInternal(skeleton); - _headIndex = _skeleton->nameToJointIndex("Head"); + //_headIndex = _skeleton->nameToJointIndex("Head"); _hipsIndex = _skeleton->nameToJointIndex("Hips"); - _spine2Index = _skeleton->nameToJointIndex("Spine2"); lookUpIndices(); } @@ -224,20 +281,20 @@ static CubicHermiteSplineFunctorWithArcLength computeSplineFromTipAndBase(const void AnimSplineIK::solveTargetWithSpline(const AnimContext& context, const IKTarget& target, const AnimPoseVec& absolutePoses, bool debug, AnimChain& chainInfoOut) const { - const int baseIndex = _hipsIndex; - const int headBaseIndex = _spine2Index; + const int baseIndex = _baseJointIndex; + const int tipBaseIndex = _secondaryTargetIndex; // build spline from tip to base AnimPose tipPose = AnimPose(glm::vec3(1.0f), target.getRotation(), target.getTranslation()); AnimPose basePose; - //if (target.getIndex() == _headIndex) { - // basePose = absolutePoses[headBaseIndex]; + //if (target.getIndex() == _tipJointIndex) { + // basePose = absolutePoses[tipBaseIndex]; //} else { basePose = absolutePoses[baseIndex]; //} CubicHermiteSplineFunctorWithArcLength spline; - if (target.getIndex() == _headIndex) { + if (target.getIndex() == _tipJointIndex) { // set gain factors so that more curvature occurs near the tip of the spline. const float HIPS_GAIN = 0.5f; const float HEAD_GAIN = 1.0f; @@ -268,7 +325,7 @@ void AnimSplineIK::solveTargetWithSpline(const AnimContext& context, const IKTar // for head splines, preform most twist toward the tip by using ease in function. t^2 float rotT = t; - if (target.getIndex() == _headIndex) { + if (target.getIndex() == _tipJointIndex) { rotT = t * t; } glm::quat twistRot = safeLerp(basePose.rot(), tipPose.rot(), rotT); @@ -290,7 +347,7 @@ void AnimSplineIK::solveTargetWithSpline(const AnimContext& context, const IKTar AnimPose relPose = parentAbsPose.inverse() * flexedAbsPose; bool constrained = false; - if (splineJointInfo.jointIndex != _hipsIndex) { + if (splineJointInfo.jointIndex != _baseJointIndex) { // constrain the amount the spine can stretch or compress float length = glm::length(relPose.trans()); const float EPSILON = 0.0001f; @@ -350,15 +407,15 @@ void AnimSplineIK::computeAndCacheSplineJointInfosForIKTarget(const AnimContext& // build spline between the default poses. AnimPose tipPose = _skeleton->getAbsoluteDefaultPose(target.getIndex()); AnimPose basePose; - if (target.getIndex() == _headIndex) { - basePose = _skeleton->getAbsoluteDefaultPose(_hipsIndex); - //basePose = _skeleton->getAbsoluteDefaultPose(_spine2Index); + if (target.getIndex() == _tipJointIndex) { + basePose = _skeleton->getAbsoluteDefaultPose(_baseJointIndex); + //basePose = _skeleton->getAbsoluteDefaultPose(_secondaryTargetIndex); } else { - basePose = _skeleton->getAbsoluteDefaultPose(_hipsIndex); + basePose = _skeleton->getAbsoluteDefaultPose(_baseJointIndex); } CubicHermiteSplineFunctorWithArcLength spline; - if (target.getIndex() == _headIndex) { + if (target.getIndex() == _tipJointIndex) { // set gain factors so that more curvature occurs near the tip of the spline. const float HIPS_GAIN = 0.5f; const float HEAD_GAIN = 1.0f; @@ -377,11 +434,11 @@ void AnimSplineIK::computeAndCacheSplineJointInfosForIKTarget(const AnimContext& int index = target.getIndex(); int endIndex; - if (target.getIndex() == _headIndex) { - endIndex = _skeleton->getParentIndex(_spine2Index); - // endIndex = _skeleton->getParentIndex(_hipsIndex); + if (target.getIndex() == _tipJointIndex) { + //endIndex = _skeleton->getParentIndex(_secondaryTargetIndex); + endIndex = _skeleton->getParentIndex(_baseJointIndex); } else { - endIndex = _skeleton->getParentIndex(_hipsIndex); + endIndex = _skeleton->getParentIndex(_baseJointIndex); } while (index != endIndex) { AnimPose defaultPose = _skeleton->getAbsoluteDefaultPose(index); @@ -410,11 +467,34 @@ void AnimSplineIK::computeAndCacheSplineJointInfosForIKTarget(const AnimContext& _splineJointInfoMap[target.getIndex()] = splineJointInfoVec; } -void AnimSplineIK ::loadPoses(const AnimPoseVec& poses) { +void AnimSplineIK::loadPoses(const AnimPoseVec& poses) { assert(_skeleton && ((poses.size() == 0) || (_skeleton->getNumJoints() == (int)poses.size()))); if (_skeleton->getNumJoints() == (int)poses.size()) { _poses = poses; } else { _poses.clear(); } +} + + +void AnimSplineIK::setTargetVars(const QString& jointName, const QString& positionVar, const QString& rotationVar, + const QString& typeVar, const QString& weightVar, float weight, const std::vector& flexCoefficients, + const QString& poleVectorEnabledVar, const QString& poleReferenceVectorVar, const QString& poleVectorVar) { + /* + IKTargetVar targetVar(jointName, positionVar, rotationVar, typeVar, weightVar, weight, flexCoefficients, poleVectorEnabledVar, poleReferenceVectorVar, poleVectorVar); + + // if there are dups, last one wins. + bool found = false; + for (auto& targetVarIter : _targetVarVec) { + if (targetVarIter.jointName == jointName) { + targetVarIter = targetVar; + found = true; + break; + } + } + if (!found) { + // create a new entry + _targetVarVec.push_back(targetVar); + } + */ } \ No newline at end of file diff --git a/libraries/animation/src/AnimSplineIK.h b/libraries/animation/src/AnimSplineIK.h index 12f43fa680..4c51a0b9e1 100644 --- a/libraries/animation/src/AnimSplineIK.h +++ b/libraries/animation/src/AnimSplineIK.h @@ -21,7 +21,12 @@ public: AnimSplineIK(const QString& id, float alpha, bool enabled, float interpDuration, const QString& baseJointName, const QString& tipJointName, const QString& alphaVar, const QString& enabledVar, - const QString& endEffectorRotationVarVar, const QString& endEffectorPositionVarVar); + const QString& endEffectorRotationVarVar, const QString& endEffectorPositionVarVar, + const QString& basePositionVar, const QString& baseRotationVar, + const QString& tipPositionVar, const QString& tipRotationVar, + const QString& secondaryTargetJointName, + const QString& secondaryTargetPositionVar, + const QString& secondaryTargetRotationVar); virtual ~AnimSplineIK() override; virtual const AnimPoseVec& evaluate(const AnimVariantMap& animVars, const AnimContext& context, float dt, AnimVariantMap& triggersOut) override; @@ -52,9 +57,17 @@ protected: float _interpDuration; QString _baseJointName; QString _tipJointName; + QString _secondaryTargetJointName; + QString _basePositionVar; + QString _baseRotationVar; + QString _tipPositionVar; + QString _tipRotationVar; + QString _secondaryTargetPositionVar; + QString _secondaryTargetRotationVar; int _baseParentJointIndex { -1 }; int _baseJointIndex { -1 }; + int _secondaryTargetIndex { -1 }; int _tipJointIndex { -1 }; int _headIndex { -1 }; int _hipsIndex { -1 }; @@ -69,6 +82,8 @@ protected: QString _prevEndEffectorRotationVar; QString _prevEndEffectorPositionVar; + bool _previousEnableDebugIKTargets { false }; + InterpType _interpType{ InterpType::None }; float _interpAlphaVel{ 0.0f }; float _interpAlpha{ 0.0f }; @@ -84,6 +99,9 @@ protected: bool _lastEnableDebugDrawIKTargets{ false }; void AnimSplineIK::solveTargetWithSpline(const AnimContext& context, const IKTarget& target, const AnimPoseVec& absolutePoses, bool debug, AnimChain& chainInfoOut) const; + void AnimSplineIK::setTargetVars(const QString& jointName, const QString& positionVar, const QString& rotationVar, + const QString& typeVar, const QString& weightVar, float weight, const std::vector& flexCoefficients, + const QString& poleVectorEnabledVar, const QString& poleReferenceVectorVar, const QString& poleVectorVar); void computeAndCacheSplineJointInfosForIKTarget(const AnimContext& context, const IKTarget& target) const; const std::vector* findOrCreateSplineJointInfo(const AnimContext& context, const IKTarget& target) const; mutable std::map> _splineJointInfoMap; diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index 70f1f9a1f7..b92e095b4f 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -1857,14 +1857,14 @@ void Rig::updateFromControllerParameters(const ControllerParameters& params, flo updateHead(_headEnabled, hipsEnabled, params.primaryControllerPoses[PrimaryControllerType_Head]); - updateHands(leftHandEnabled, rightHandEnabled, hipsEnabled, hipsEstimated, leftArmEnabled, rightArmEnabled, _headEnabled, dt, - params.primaryControllerPoses[PrimaryControllerType_LeftHand], params.primaryControllerPoses[PrimaryControllerType_RightHand], - params.hipsShapeInfo, params.spineShapeInfo, params.spine1ShapeInfo, params.spine2ShapeInfo, - params.rigToSensorMatrix, sensorToRigMatrix); + //updateHands(leftHandEnabled, rightHandEnabled, hipsEnabled, hipsEstimated, leftArmEnabled, rightArmEnabled, _headEnabled, dt, + // params.primaryControllerPoses[PrimaryControllerType_LeftHand], params.primaryControllerPoses[PrimaryControllerType_RightHand], + // params.hipsShapeInfo, params.spineShapeInfo, params.spine1ShapeInfo, params.spine2ShapeInfo, + // params.rigToSensorMatrix, sensorToRigMatrix); - //updateHands2(leftHandEnabled, rightHandEnabled, _headEnabled, - // params.primaryControllerPoses[PrimaryControllerType_LeftHand], params.primaryControllerPoses[PrimaryControllerType_RightHand], - // params.rigToSensorMatrix, sensorToRigMatrix); + updateHands2(leftHandEnabled, rightHandEnabled, _headEnabled, + params.primaryControllerPoses[PrimaryControllerType_LeftHand], params.primaryControllerPoses[PrimaryControllerType_RightHand], + params.rigToSensorMatrix, sensorToRigMatrix); updateFeet(leftFootEnabled, rightFootEnabled, _headEnabled, params.primaryControllerPoses[PrimaryControllerType_LeftFoot], params.primaryControllerPoses[PrimaryControllerType_RightFoot], From e7941f78d67f99844697e8563957129e7e865c9a Mon Sep 17 00:00:00 2001 From: amantley Date: Thu, 24 Jan 2019 17:17:39 -0800 Subject: [PATCH 015/112] adding the shoulder rotation back in --- libraries/animation/src/AnimSplineIK.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/libraries/animation/src/AnimSplineIK.cpp b/libraries/animation/src/AnimSplineIK.cpp index afe9f6dfcb..1f135df120 100644 --- a/libraries/animation/src/AnimSplineIK.cpp +++ b/libraries/animation/src/AnimSplineIK.cpp @@ -125,8 +125,8 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const AnimPose afterSolveSecondaryTarget = _skeleton->getAbsolutePose(_secondaryTargetIndex, _poses); glm::quat secondaryTargetRotation = animVars.lookupRigToGeometry(_secondaryTargetRotationVar, afterSolveSecondaryTarget.rot()); - // updatedSecondaryTarget = AnimPose(secondaryTargetRotation, afterSolveSpine2.trans()); - updatedSecondaryTarget = AnimPose(afterSolveSecondaryTarget.rot(), afterSolveSecondaryTarget.trans()); + updatedSecondaryTarget = AnimPose(secondaryTargetRotation, afterSolveSecondaryTarget.trans()); + //updatedSecondaryTarget = AnimPose(afterSolveSecondaryTarget.rot(), afterSolveSecondaryTarget.trans()); } @@ -141,10 +141,10 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const secondaryTarget.setPose(updatedSecondaryTarget.rot(), updatedSecondaryTarget.trans()); secondaryTarget.setWeight(weight2); - const float* flexCoefficients2 = new float[3]{ 1.0f, 1.0f, 1.0f }; + const float* flexCoefficients2 = new float[3]{ 1.0f, 0.5f, 0.25f }; secondaryTarget.setFlexCoefficients(3, flexCoefficients2); } - /* + AnimChain secondaryJointChain; AnimPose beforeSolveChestNeck; if (_poses.size() > 0) { @@ -157,7 +157,7 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const secondaryJointChain.outputRelativePoses(_poses); } - */ + const float FRAMES_PER_SECOND = 30.0f; _interpAlphaVel = FRAMES_PER_SECOND / _interpDuration; @@ -183,9 +183,9 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const AnimPose finalNeckAbsolute = AnimPose(safeLerp(target2.getRotation(), target.getRotation(), 1.0f),neckAbsolute.trans()); _poses[headParent] = spine2Target.inverse() * beforeSolveChestNeck; */ - //AnimPose tipTarget(target.getRotation(),target.getTranslation()); - //AnimPose tipRelativePose = _skeleton->getAbsolutePose(tipParent,_poses).inverse() * headTarget; - //_poses[_tipJointIndex] = tipHeadRelativePose; + AnimPose tipTarget(target.getRotation(),target.getTranslation()); + AnimPose tipRelativePose = _skeleton->getAbsolutePose(tipParent,_poses).inverse() * tipTarget; + _poses[_tipJointIndex] = tipRelativePose; } // debug render ik targets From 2574e821840952b694c463ece9bfbb5fc27aa1b9 Mon Sep 17 00:00:00 2001 From: amantley Date: Thu, 24 Jan 2019 19:47:27 -0800 Subject: [PATCH 016/112] cleaned up print statements --- interface/src/avatar/MySkeletonModel.cpp | 5 +---- .../animation/src/AnimInverseKinematics.cpp | 21 +++++-------------- libraries/animation/src/AnimTwoBoneIK.cpp | 3 --- 3 files changed, 6 insertions(+), 23 deletions(-) diff --git a/interface/src/avatar/MySkeletonModel.cpp b/interface/src/avatar/MySkeletonModel.cpp index e0362ef548..356b365f93 100644 --- a/interface/src/avatar/MySkeletonModel.cpp +++ b/interface/src/avatar/MySkeletonModel.cpp @@ -199,7 +199,7 @@ void MySkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) { // if hips are not under direct control, estimate the hips position. if (avatarHeadPose.isValid() && !(params.primaryControllerFlags[Rig::PrimaryControllerType_Hips] & (uint8_t)Rig::ControllerFlags::Enabled)) { bool isFlying = (myAvatar->getCharacterController()->getState() == CharacterController::State::Hover || myAvatar->getCharacterController()->computeCollisionGroup() == BULLET_COLLISION_GROUP_COLLISIONLESS); - + // timescale in seconds const float TRANS_HORIZ_TIMESCALE = 0.15f; const float TRANS_VERT_TIMESCALE = 0.01f; // We want the vertical component of the hips to follow quickly to prevent spine squash/stretch. @@ -255,9 +255,6 @@ void MySkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) { AnimPose newSpinePose(glm::mat4(glm::vec4(w, 0.0f), glm::vec4(u, 0.0f), glm::vec4(v, 0.0f), glm::vec4(glm::vec3(0.0f, 0.0f, 0.0f), 1.0f))); currentSpine2Pose.rot() = safeLerp(currentSpine2Pose.rot(), newSpinePose.rot(), SPINE2_ROTATION_FILTER); params.primaryControllerPoses[Rig::PrimaryControllerType_Spine2] = currentSpine2Pose; - qCDebug(interfaceapp) << "finding the spine 2 azimuth"; - qCDebug(interfaceapp) << currentSpine2Pose; - params.primaryControllerFlags[Rig::PrimaryControllerType_Spine2] = (uint8_t)Rig::ControllerFlags::Enabled | (uint8_t)Rig::ControllerFlags::Estimated; } } diff --git a/libraries/animation/src/AnimInverseKinematics.cpp b/libraries/animation/src/AnimInverseKinematics.cpp index f95fe3333f..a1809f3438 100644 --- a/libraries/animation/src/AnimInverseKinematics.cpp +++ b/libraries/animation/src/AnimInverseKinematics.cpp @@ -237,7 +237,6 @@ void AnimInverseKinematics::solve(const AnimContext& context, const std::vector< // solve all targets for (size_t i = 0; i < targets.size(); i++) { - // qCDebug(animation) << "target id: " << targets[i].getIndex() << " and type " << (int)targets[i].getType(); switch (targets[i].getType()) { case IKTarget::Type::Unknown: break; @@ -259,7 +258,6 @@ void AnimInverseKinematics::solve(const AnimContext& context, const std::vector< // ease in expo alpha = 1.0f - powf(2.0f, -10.0f * alpha); - qCDebug(animation) << "the alpha for joint chains is " << alpha; size_t chainSize = std::min(_prevJointChainInfoVec[i].jointInfoVec.size(), jointChainInfoVec[i].jointInfoVec.size()); @@ -322,10 +320,6 @@ void AnimInverseKinematics::solve(const AnimContext& context, const std::vector< } } - //qCDebug(animation) << "joint chain pose for head animIK " << jointChainInfoVec[4].jointInfoVec[w].trans << " " << jointChainInfoVec[4].jointInfoVec[w].rot; - qCDebug(animation) << "absolute pose for head animIK " << absolutePoses[_skeleton->nameToJointIndex("Head")]; - qCDebug(animation) << "target pose for head animIK " << targets[4].getTranslation() << " " << targets[4].getRotation(); - // compute maxError maxError = 0.0f; for (size_t i = 0; i < targets.size(); i++) { @@ -366,7 +360,6 @@ void AnimInverseKinematics::solve(const AnimContext& context, const std::vector< // copy jointChainInfoVec into _prevJointChainInfoVec, and update timers for (size_t i = 0; i < jointChainInfoVec.size(); i++) { _prevJointChainInfoVec[i].timer = _prevJointChainInfoVec[i].timer - dt; - //qCDebug(animation) << "the alpha for joint chains is " << _prevJointChainInfoVec[i].timer; if (_prevJointChainInfoVec[i].timer <= 0.0f) { _prevJointChainInfoVec[i] = jointChainInfoVec[i]; _prevJointChainInfoVec[i].target = targets[i]; @@ -830,9 +823,7 @@ void AnimInverseKinematics::solveTargetWithSpline(const AnimContext& context, co AnimPose relPose = parentAbsPose.inverse() * flexedAbsPose; - bool constrained = false; - /* if (splineJointInfo.jointIndex != _hipsIndex) { // constrain the amount the spine can stretch or compress float length = glm::length(relPose.trans()); @@ -853,7 +844,7 @@ void AnimInverseKinematics::solveTargetWithSpline(const AnimContext& context, co relPose.trans() = glm::vec3(0.0f); } } - */ + jointChainInfoOut.jointInfoVec[i] = { relPose.rot(), relPose.trans(), splineJointInfo.jointIndex, constrained }; parentAbsPose = flexedAbsPose; @@ -878,6 +869,7 @@ const AnimPoseVec& AnimInverseKinematics::overlay(const AnimVariantMap& animVars // disable IK on android return underPoses; #endif + // allows solutionSource to be overridden by an animVar auto solutionSource = animVars.lookup(_solutionSourceVar, (int)_solutionSource); @@ -885,7 +877,7 @@ const AnimPoseVec& AnimInverseKinematics::overlay(const AnimVariantMap& animVars if (dt > MAX_OVERLAY_DT) { dt = MAX_OVERLAY_DT; } - + if (_relativePoses.size() != underPoses.size()) { loadPoses(underPoses); } else { @@ -1040,20 +1032,17 @@ const AnimPoseVec& AnimInverseKinematics::overlay(const AnimVariantMap& animVars preconditionRelativePosesToAvoidLimbLock(context, targets); - //qCDebug(animation) << "hips before ccd" << _relativePoses[_hipsIndex]; solve(context, targets, dt, jointChainInfoVec); - //qCDebug(animation) << "hips after ccd" << _relativePoses[_hipsIndex]; - } } - + if (context.getEnableDebugDrawIKConstraints()) { debugDrawConstraints(context); } } processOutputJoints(triggersOut); - + return _relativePoses; } diff --git a/libraries/animation/src/AnimTwoBoneIK.cpp b/libraries/animation/src/AnimTwoBoneIK.cpp index 31397157ac..3f8de488ff 100644 --- a/libraries/animation/src/AnimTwoBoneIK.cpp +++ b/libraries/animation/src/AnimTwoBoneIK.cpp @@ -50,7 +50,6 @@ const AnimPoseVec& AnimTwoBoneIK::evaluate(const AnimVariantMap& animVars, const if (_children.size() != 1) { return _poses; } - // evalute underPoses AnimPoseVec underPoses = _children[0]->evaluate(animVars, context, dt, triggersOut); @@ -79,7 +78,6 @@ const AnimPoseVec& AnimTwoBoneIK::evaluate(const AnimVariantMap& animVars, const // determine if we should interpolate bool enabled = animVars.lookup(_enabledVar, _enabled); - // qCDebug(animation) << "two bone var " << _enabledVar; if (enabled != _enabled) { AnimChain poseChain; poseChain.buildFromRelativePoses(_skeleton, _poses, _tipJointIndex); @@ -123,7 +121,6 @@ const AnimPoseVec& AnimTwoBoneIK::evaluate(const AnimVariantMap& animVars, const // First look in the triggers then look in the animVars, so we can follow output joints underneath us in the anim graph AnimPose targetPose(tipPose); if (triggersOut.hasKey(endEffectorRotationVar)) { - qCDebug(animation) << " end effector variable " << endEffectorRotationVar << " is " << triggersOut.lookupRigToGeometry(endEffectorRotationVar, tipPose.rot()); targetPose.rot() = triggersOut.lookupRigToGeometry(endEffectorRotationVar, tipPose.rot()); } else if (animVars.hasKey(endEffectorRotationVar)) { targetPose.rot() = animVars.lookupRigToGeometry(endEffectorRotationVar, tipPose.rot()); From bc635306ead7c5c6640aa652f936ae0a3fcab98f Mon Sep 17 00:00:00 2001 From: amantley Date: Thu, 24 Jan 2019 22:28:40 -0800 Subject: [PATCH 017/112] added interp from enabled to disabled and vice versa --- libraries/animation/src/AnimSplineIK.cpp | 107 +++++++++++++++++++---- libraries/animation/src/AnimSplineIK.h | 1 + 2 files changed, 93 insertions(+), 15 deletions(-) diff --git a/libraries/animation/src/AnimSplineIK.cpp b/libraries/animation/src/AnimSplineIK.cpp index 1f135df120..a036bb47a5 100644 --- a/libraries/animation/src/AnimSplineIK.cpp +++ b/libraries/animation/src/AnimSplineIK.cpp @@ -15,6 +15,7 @@ #include "AnimUtil.h" static const float JOINT_CHAIN_INTERP_TIME = 0.5f; +static const float FRAMES_PER_SECOND = 30.0f; AnimSplineIK::AnimSplineIK(const QString& id, float alpha, bool enabled, float interpDuration, const QString& baseJointName, @@ -66,10 +67,50 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const if (_children.size() != 1) { return _poses; } + + const float MIN_ALPHA = 0.0f; + const float MAX_ALPHA = 1.0f; + float alpha = glm::clamp(animVars.lookup(_alphaVar, _alpha), MIN_ALPHA, MAX_ALPHA); + // evaluate underPoses AnimPoseVec underPoses = _children[0]->evaluate(animVars, context, dt, triggersOut); + + // if we don't have a skeleton, or jointName lookup failed. + if (!_skeleton || _baseJointIndex == -1 || _tipJointIndex == -1 || alpha == 0.0f || underPoses.size() == 0) { + // pass underPoses through unmodified. + _poses = underPoses; + return _poses; + } + + // guard against size changes + if (underPoses.size() != _poses.size()) { + _poses = underPoses; + } + + // determine if we should interpolate + bool enabled = animVars.lookup(_enabledVar, _enabled); + if (enabled != _enabled) { + AnimChain poseChain; + poseChain.buildFromRelativePoses(_skeleton, _poses, _tipJointIndex); + if (enabled) { + beginInterp(InterpType::SnapshotToSolve, poseChain); + } else { + beginInterp(InterpType::SnapshotToUnderPoses, poseChain); + } + } + _enabled = enabled; + _poses = underPoses; + // don't build chains or do IK if we are disabled & not interping. + if (_interpType == InterpType::None && !enabled) { + return _poses; + } + + // compute under chain for possible interpolation + AnimChain underChain; + underChain.buildFromRelativePoses(_skeleton, underPoses, _tipJointIndex); + glm::quat hipsTargetRotation; glm::vec3 hipsTargetTranslation; @@ -113,8 +154,7 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const AnimPoseVec absolutePoses2; absolutePoses2.resize(_poses.size()); if (_poses.size() > 0) { - - //_snapshotChain.buildFromRelativePoses(_skeleton, _poses, target.getIndex()); + jointChain.buildFromRelativePoses(_skeleton, _poses, target.getIndex()); solveTargetWithSpline(context, target, absolutePoses, false, jointChain); jointChain.buildDirtyAbsolutePoses(); @@ -149,25 +189,13 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const AnimPose beforeSolveChestNeck; if (_poses.size() > 0) { - + beforeSolveChestNeck = _skeleton->getAbsolutePose(_skeleton->nameToJointIndex("Neck"), _poses); secondaryJointChain.buildFromRelativePoses(_skeleton, _poses, secondaryTarget.getIndex()); solveTargetWithSpline(context, secondaryTarget, absolutePoses2, false, secondaryJointChain); secondaryJointChain.outputRelativePoses(_poses); } - - - - const float FRAMES_PER_SECOND = 30.0f; - _interpAlphaVel = FRAMES_PER_SECOND / _interpDuration; - _alpha = _interpAlphaVel * dt; - // we need to blend the old joint chain with the current joint chain, otherwise known as: _snapShotChain - // we blend the chain info then we accumulate it then we assign to relative poses then we return the value. - // make the alpha - // make the prevchain - // interp from the previous chain to the new chain/or underposes if the ik is disabled. - // update the relative poses and then we are done // set the tip/head rotation to match the absolute rotation of the target. int tipParent = _skeleton->getParentIndex(_tipJointIndex); @@ -188,6 +216,46 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const _poses[_tipJointIndex] = tipRelativePose; } + // compute chain + AnimChain ikChain; + ikChain.buildFromRelativePoses(_skeleton, _poses, _tipJointIndex); + // blend with the underChain + ikChain.blend(underChain, alpha); + + // apply smooth interpolation when turning ik on and off + if (_interpType != InterpType::None) { + _interpAlpha += _interpAlphaVel * dt; + + // ease in expo + float easeInAlpha = 1.0f - powf(2.0f, -10.0f * _interpAlpha); + + if (_interpAlpha < 1.0f) { + AnimChain interpChain; + if (_interpType == InterpType::SnapshotToUnderPoses) { + interpChain = underChain; + interpChain.blend(_snapshotChain, easeInAlpha); + } else if (_interpType == InterpType::SnapshotToSolve) { + interpChain = ikChain; + interpChain.blend(_snapshotChain, easeInAlpha); + } + // copy interpChain into _poses + interpChain.outputRelativePoses(_poses); + } else { + // interpolation complete + _interpType = InterpType::None; + } + } + + if (_interpType == InterpType::None) { + if (enabled) { + // copy chain into _poses + ikChain.outputRelativePoses(_poses); + } else { + // copy under chain into _poses + underChain.outputRelativePoses(_poses); + } + } + // debug render ik targets if (context.getEnableDebugDrawIKTargets()) { const vec4 WHITE(1.0f); @@ -497,4 +565,13 @@ void AnimSplineIK::setTargetVars(const QString& jointName, const QString& positi _targetVarVec.push_back(targetVar); } */ +} + +void AnimSplineIK::beginInterp(InterpType interpType, const AnimChain& chain) { + // capture the current poses in a snapshot. + _snapshotChain = chain; + + _interpType = interpType; + _interpAlphaVel = FRAMES_PER_SECOND / _interpDuration; + _interpAlpha = 0.0f; } \ No newline at end of file diff --git a/libraries/animation/src/AnimSplineIK.h b/libraries/animation/src/AnimSplineIK.h index 4c51a0b9e1..d4dbb85a9e 100644 --- a/libraries/animation/src/AnimSplineIK.h +++ b/libraries/animation/src/AnimSplineIK.h @@ -49,6 +49,7 @@ protected: virtual void setSkeletonInternal(AnimSkeleton::ConstPointer skeleton) override; void lookUpIndices(); + void beginInterp(InterpType interpType, const AnimChain& chain); AnimPoseVec _poses; From 71df61498997afb1d0e64a9b0d690630ed92ab47 Mon Sep 17 00:00:00 2001 From: amantley Date: Fri, 25 Jan 2019 11:28:37 -0800 Subject: [PATCH 018/112] put all the hand update code in one function that works for two bone IK and legacy animInverseKinematics Ik --- libraries/animation/src/AnimSplineIK.cpp | 13 +++---- libraries/animation/src/Rig.cpp | 45 +++++++++++++++++++----- 2 files changed, 43 insertions(+), 15 deletions(-) diff --git a/libraries/animation/src/AnimSplineIK.cpp b/libraries/animation/src/AnimSplineIK.cpp index a036bb47a5..bb3ec654f5 100644 --- a/libraries/animation/src/AnimSplineIK.cpp +++ b/libraries/animation/src/AnimSplineIK.cpp @@ -189,7 +189,7 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const AnimPose beforeSolveChestNeck; if (_poses.size() > 0) { - + // fix this to deal with no neck AA beforeSolveChestNeck = _skeleton->getAbsolutePose(_skeleton->nameToJointIndex("Neck"), _poses); secondaryJointChain.buildFromRelativePoses(_skeleton, _poses, secondaryTarget.getIndex()); @@ -205,12 +205,13 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const AnimPose secondaryTargetPose(target2.getRotation(), target2.getTranslation()); AnimPose secondaryTargetRelativePose = _skeleton->getAbsolutePose(secondaryTargetParent, _poses).inverse() * secondaryTargetPose; _poses[_secondaryTargetIndex] = secondaryTargetRelativePose; - - - AnimPose neckAbsolute = _skeleton->getAbsolutePose(tipParent, _poses); - AnimPose finalNeckAbsolute = AnimPose(safeLerp(target2.getRotation(), target.getRotation(), 1.0f),neckAbsolute.trans()); - _poses[headParent] = spine2Target.inverse() * beforeSolveChestNeck; */ + + AnimPose secondaryTargetPose(secondaryTarget.getRotation(), secondaryTarget.getTranslation()); + AnimPose neckAbsolute = _skeleton->getAbsolutePose(tipParent, _poses); + //AnimPose finalNeckAbsolute = AnimPose(safeLerp(target2.getRotation(), target.getRotation(), 1.0f),neckAbsolute.trans()); + _poses[tipParent] = secondaryTargetPose.inverse() * beforeSolveChestNeck; + AnimPose tipTarget(target.getRotation(),target.getTranslation()); AnimPose tipRelativePose = _skeleton->getAbsolutePose(tipParent,_poses).inverse() * tipTarget; _poses[_tipJointIndex] = tipRelativePose; diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index b92e095b4f..9e2e099cfe 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -1271,6 +1271,7 @@ void Rig::computeHeadFromHMD(const AnimPose& hmdPose, glm::vec3& headPositionOut void Rig::updateHead(bool headEnabled, bool hipsEnabled, const AnimPose& headPose) { if (_animSkeleton) { if (headEnabled) { + _animVars.set("splineIKEnabled", true); _animVars.set("headPosition", headPose.trans()); _animVars.set("headRotation", headPose.rot()); if (hipsEnabled) { @@ -1285,6 +1286,7 @@ void Rig::updateHead(bool headEnabled, bool hipsEnabled, const AnimPose& headPos _animVars.set("headWeight", 8.0f); } } else { + _animVars.set("splineIKEnabled", false); _animVars.unset("headPosition"); _animVars.set("headRotation", headPose.rot()); _animVars.set("headType", (int)IKTarget::Type::RotationOnly); @@ -1416,8 +1418,22 @@ void Rig::updateHands(bool leftHandEnabled, bool rightHandEnabled, bool hipsEnab const bool ENABLE_POLE_VECTORS = true; + if (headEnabled) { + // always do IK if head is enabled + _animVars.set("leftHandIKEnabled", true); + _animVars.set("rightHandIKEnabled", true); + } else { + // only do IK if we have a valid foot. + _animVars.set("leftHandIKEnabled", leftHandEnabled); + _animVars.set("rightHandIKEnabled", rightHandEnabled); + } + if (leftHandEnabled) { + // we need this for twoBoneIK version of hands. + _animVars.set(LEFT_HAND_IK_POSITION_VAR, LEFT_HAND_POSITION); + _animVars.set(LEFT_HAND_IK_ROTATION_VAR, LEFT_HAND_ROTATION); + glm::vec3 handPosition = leftHandPose.trans(); glm::quat handRotation = leftHandPose.rot(); @@ -1450,8 +1466,11 @@ void Rig::updateHands(bool leftHandEnabled, bool rightHandEnabled, bool hipsEnab _animVars.set("leftHandPoleVectorEnabled", false); } } else { + // need this for two bone ik + _animVars.set(LEFT_HAND_IK_POSITION_VAR, MAIN_STATE_MACHINE_LEFT_HAND_POSITION); + _animVars.set(LEFT_HAND_IK_ROTATION_VAR, MAIN_STATE_MACHINE_LEFT_HAND_ROTATION); + _animVars.set("leftHandPoleVectorEnabled", false); - _animVars.unset("leftHandPosition"); _animVars.unset("leftHandRotation"); @@ -1465,6 +1484,10 @@ void Rig::updateHands(bool leftHandEnabled, bool rightHandEnabled, bool hipsEnab if (rightHandEnabled) { + // need this for two bone IK + _animVars.set(RIGHT_HAND_IK_POSITION_VAR, RIGHT_HAND_POSITION); + _animVars.set(RIGHT_HAND_IK_ROTATION_VAR, RIGHT_HAND_ROTATION); + glm::vec3 handPosition = rightHandPose.trans(); glm::quat handRotation = rightHandPose.rot(); @@ -1498,8 +1521,12 @@ void Rig::updateHands(bool leftHandEnabled, bool rightHandEnabled, bool hipsEnab _animVars.set("rightHandPoleVectorEnabled", false); } } else { - _animVars.set("rightHandPoleVectorEnabled", false); + // need this for two bone IK + _animVars.set(RIGHT_HAND_IK_POSITION_VAR, MAIN_STATE_MACHINE_RIGHT_HAND_POSITION); + _animVars.set(RIGHT_HAND_IK_ROTATION_VAR, MAIN_STATE_MACHINE_RIGHT_HAND_ROTATION); + + _animVars.set("rightHandPoleVectorEnabled", false); _animVars.unset("rightHandPosition"); _animVars.unset("rightHandRotation"); @@ -1857,14 +1884,14 @@ void Rig::updateFromControllerParameters(const ControllerParameters& params, flo updateHead(_headEnabled, hipsEnabled, params.primaryControllerPoses[PrimaryControllerType_Head]); - //updateHands(leftHandEnabled, rightHandEnabled, hipsEnabled, hipsEstimated, leftArmEnabled, rightArmEnabled, _headEnabled, dt, - // params.primaryControllerPoses[PrimaryControllerType_LeftHand], params.primaryControllerPoses[PrimaryControllerType_RightHand], - // params.hipsShapeInfo, params.spineShapeInfo, params.spine1ShapeInfo, params.spine2ShapeInfo, - // params.rigToSensorMatrix, sensorToRigMatrix); + updateHands(leftHandEnabled, rightHandEnabled, hipsEnabled, hipsEstimated, leftArmEnabled, rightArmEnabled, _headEnabled, dt, + params.primaryControllerPoses[PrimaryControllerType_LeftHand], params.primaryControllerPoses[PrimaryControllerType_RightHand], + params.hipsShapeInfo, params.spineShapeInfo, params.spine1ShapeInfo, params.spine2ShapeInfo, + params.rigToSensorMatrix, sensorToRigMatrix); - updateHands2(leftHandEnabled, rightHandEnabled, _headEnabled, - params.primaryControllerPoses[PrimaryControllerType_LeftHand], params.primaryControllerPoses[PrimaryControllerType_RightHand], - params.rigToSensorMatrix, sensorToRigMatrix); + //updateHands2(leftHandEnabled, rightHandEnabled, _headEnabled, + // params.primaryControllerPoses[PrimaryControllerType_LeftHand], params.primaryControllerPoses[PrimaryControllerType_RightHand], + // params.rigToSensorMatrix, sensorToRigMatrix); updateFeet(leftFootEnabled, rightFootEnabled, _headEnabled, params.primaryControllerPoses[PrimaryControllerType_LeftFoot], params.primaryControllerPoses[PrimaryControllerType_RightFoot], From 992820cd674dfc37fc31c8517b81bf1ecc4e5e3e Mon Sep 17 00:00:00 2001 From: amantley Date: Fri, 25 Jan 2019 11:34:18 -0800 Subject: [PATCH 019/112] removed unnecessary hand update function for two bone IK --- libraries/animation/src/Rig.cpp | 102 -------------------------------- libraries/animation/src/Rig.h | 3 - 2 files changed, 105 deletions(-) diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index 9e2e099cfe..7a6a1530d7 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -1539,104 +1539,6 @@ void Rig::updateHands(bool leftHandEnabled, bool rightHandEnabled, bool hipsEnab } } -void Rig::updateHands2(bool leftHandEnabled, bool rightHandEnabled, bool headEnabled, - const AnimPose& leftHandPose, const AnimPose& rightHandPose, - const glm::mat4& rigToSensorMatrix, const glm::mat4& sensorToRigMatrix) { - - int hipsIndex = indexOfJoint("Hips"); - const float ELBOW_POLE_VECTOR_BLEND_FACTOR = 0.85f; - - if (headEnabled) { - // always do IK if head is enabled - _animVars.set("leftHandIKEnabled", true); - _animVars.set("rightHandIKEnabled", true); - } else { - // only do IK if we have a valid foot. - _animVars.set("leftHandIKEnabled", leftHandEnabled); - _animVars.set("rightHandIKEnabled", rightHandEnabled); - } - - if (leftHandEnabled) { - - _animVars.set(LEFT_HAND_POSITION, leftHandPose.trans()); - _animVars.set(LEFT_HAND_ROTATION, leftHandPose.rot()); - - // We want to drive the IK directly from the trackers. - _animVars.set(LEFT_HAND_IK_POSITION_VAR, LEFT_HAND_POSITION); - _animVars.set(LEFT_HAND_IK_ROTATION_VAR, LEFT_HAND_ROTATION); - - int handJointIndex = _animSkeleton->nameToJointIndex("LeftHand"); - int elbowJointIndex = _animSkeleton->nameToJointIndex("LeftForeArm"); - int shoulderJointIndex = _animSkeleton->nameToJointIndex("LeftArm"); - int oppositeArmJointIndex = _animSkeleton->nameToJointIndex("RightArm"); - glm::vec3 poleVector; - bool usePoleVector = calculateElbowPoleVector(handJointIndex, elbowJointIndex, shoulderJointIndex, oppositeArmJointIndex, poleVector); - //glm::vec3 poleVector = calculateKneePoleVector(handJointIndex, elbowJointIndex, shoulderJointIndex, hipsIndex, rightHandPose); - glm::vec3 sensorPoleVector = transformVectorFast(rigToSensorMatrix, poleVector); - - // smooth toward desired pole vector from previous pole vector... to reduce jitter, but in sensor space. - if (!_prevLeftHandPoleVectorValid) { - _prevLeftHandPoleVectorValid = true; - _prevLeftHandPoleVector = sensorPoleVector; - } - glm::quat deltaRot = rotationBetween(_prevLeftHandPoleVector, sensorPoleVector); - glm::quat smoothDeltaRot = safeMix(deltaRot, Quaternions::IDENTITY, ELBOW_POLE_VECTOR_BLEND_FACTOR); - _prevLeftHandPoleVector = smoothDeltaRot * _prevLeftHandPoleVector; - - _animVars.set("leftHandPoleVectorEnabled", true); - _animVars.set("leftHandPoleVector", transformVectorFast(sensorToRigMatrix, _prevLeftHandPoleVector)); - } else { - // We want to drive the IK from the underlying animation. - // This gives us the ability to squat while in the HMD, without the feet from dipping under the floor. - _animVars.set(LEFT_HAND_IK_POSITION_VAR, MAIN_STATE_MACHINE_LEFT_HAND_POSITION); - _animVars.set(LEFT_HAND_IK_ROTATION_VAR, MAIN_STATE_MACHINE_LEFT_HAND_ROTATION); - - // We want to match the animated knee pose as close as possible, so don't use poleVectors - _animVars.set("leftHandPoleVectorEnabled", false); - _prevLeftHandPoleVectorValid = false; - } - - if (rightHandEnabled) { - - _animVars.set(RIGHT_HAND_POSITION, rightHandPose.trans()); - _animVars.set(RIGHT_HAND_ROTATION, rightHandPose.rot()); - - // We want to drive the IK directly from the trackers. - _animVars.set(RIGHT_HAND_IK_POSITION_VAR, RIGHT_HAND_POSITION); - _animVars.set(RIGHT_HAND_IK_ROTATION_VAR, RIGHT_HAND_ROTATION); - - int handJointIndex = _animSkeleton->nameToJointIndex("RightHand"); - int elbowJointIndex = _animSkeleton->nameToJointIndex("RightForeArm"); - int shoulderJointIndex = _animSkeleton->nameToJointIndex("RightArm"); - int oppositeArmJointIndex = _animSkeleton->nameToJointIndex("LeftArm"); - glm::vec3 poleVector; - bool usePoleVector = calculateElbowPoleVector(handJointIndex, elbowJointIndex, shoulderJointIndex, oppositeArmJointIndex, poleVector); - glm::vec3 sensorPoleVector = transformVectorFast(rigToSensorMatrix, poleVector); - - // smooth toward desired pole vector from previous pole vector... to reduce jitter, but in sensor space. - if (!_prevRightHandPoleVectorValid) { - _prevRightHandPoleVectorValid = true; - _prevRightHandPoleVector = sensorPoleVector; - } - glm::quat deltaRot = rotationBetween(_prevRightHandPoleVector, sensorPoleVector); - glm::quat smoothDeltaRot = safeMix(deltaRot, Quaternions::IDENTITY, ELBOW_POLE_VECTOR_BLEND_FACTOR); - _prevRightHandPoleVector = smoothDeltaRot * _prevRightHandPoleVector; - - _animVars.set("rightHandPoleVectorEnabled", true); - _animVars.set("rightHandPoleVector", transformVectorFast(sensorToRigMatrix, _prevRightHandPoleVector)); - } else { - // We want to drive the IK from the underlying animation. - // This gives us the ability to squat while in the HMD, without the feet from dipping under the floor. - _animVars.set(RIGHT_HAND_IK_POSITION_VAR, MAIN_STATE_MACHINE_RIGHT_HAND_POSITION); - _animVars.set(RIGHT_HAND_IK_ROTATION_VAR, MAIN_STATE_MACHINE_RIGHT_HAND_ROTATION); - - // We want to match the animated knee pose as close as possible, so don't use poleVectors - _animVars.set("rightHandPoleVectorEnabled", false); - _prevRightHandPoleVectorValid = false; - } - -} - void Rig::updateFeet(bool leftFootEnabled, bool rightFootEnabled, bool headEnabled, const AnimPose& leftFootPose, const AnimPose& rightFootPose, const glm::mat4& rigToSensorMatrix, const glm::mat4& sensorToRigMatrix) { @@ -1889,10 +1791,6 @@ void Rig::updateFromControllerParameters(const ControllerParameters& params, flo params.hipsShapeInfo, params.spineShapeInfo, params.spine1ShapeInfo, params.spine2ShapeInfo, params.rigToSensorMatrix, sensorToRigMatrix); - //updateHands2(leftHandEnabled, rightHandEnabled, _headEnabled, - // params.primaryControllerPoses[PrimaryControllerType_LeftHand], params.primaryControllerPoses[PrimaryControllerType_RightHand], - // params.rigToSensorMatrix, sensorToRigMatrix); - updateFeet(leftFootEnabled, rightFootEnabled, _headEnabled, params.primaryControllerPoses[PrimaryControllerType_LeftFoot], params.primaryControllerPoses[PrimaryControllerType_RightFoot], params.rigToSensorMatrix, sensorToRigMatrix); diff --git a/libraries/animation/src/Rig.h b/libraries/animation/src/Rig.h index e6effe9e53..7468e9f6f9 100644 --- a/libraries/animation/src/Rig.h +++ b/libraries/animation/src/Rig.h @@ -250,9 +250,6 @@ protected: const HFMJointShapeInfo& hipsShapeInfo, const HFMJointShapeInfo& spineShapeInfo, const HFMJointShapeInfo& spine1ShapeInfo, const HFMJointShapeInfo& spine2ShapeInfo, const glm::mat4& rigToSensorMatrix, const glm::mat4& sensorToRigMatrix); - void updateHands2(bool leftHandEnabled, bool rightHandEnabled, bool headEnabled, - const AnimPose& leftHandPose, const AnimPose& rightHandPose, - const glm::mat4& rigToSensorMatrix, const glm::mat4& sensorToRigMatrix); void updateFeet(bool leftFootEnabled, bool rightFootEnabled, bool headEnabled, const AnimPose& leftFootPose, const AnimPose& rightFootPose, const glm::mat4& rigToSensorMatrix, const glm::mat4& sensorToRigMatrix); From 446d7b9514e6b1b87384b78b99e984d6f48134ee Mon Sep 17 00:00:00 2001 From: amantley Date: Fri, 25 Jan 2019 14:41:18 -0800 Subject: [PATCH 020/112] added the flex coeff for the primary and secondary spline targets to the json --- .../avatar/avatar-animation_withIKNode.json | 4 ++- libraries/animation/src/AnimNodeLoader.cpp | 5 +++- libraries/animation/src/AnimSplineIK.cpp | 30 ++++++++++++++++--- libraries/animation/src/AnimSplineIK.h | 12 +++++++- 4 files changed, 44 insertions(+), 7 deletions(-) diff --git a/interface/resources/avatar/avatar-animation_withIKNode.json b/interface/resources/avatar/avatar-animation_withIKNode.json index 04ed593755..13c102a5f1 100644 --- a/interface/resources/avatar/avatar-animation_withIKNode.json +++ b/interface/resources/avatar/avatar-animation_withIKNode.json @@ -193,7 +193,9 @@ "alphaVar": "splineIKAlpha", "enabledVar": "splineIKEnabled", "endEffectorRotationVarVar": "splineIKRotationVar", - "endEffectorPositionVarVar": "splineIKPositionVar" + "endEffectorPositionVarVar": "splineIKPositionVar", + "primaryFlexCoefficients": "1, 0.5, 0.25, 0.2, 0.1", + "secondaryFlexCoefficients": "1.0, 0.5, 0.25" }, "children": [ { diff --git a/libraries/animation/src/AnimNodeLoader.cpp b/libraries/animation/src/AnimNodeLoader.cpp index ebe9dbe3ba..c5d17e8884 100644 --- a/libraries/animation/src/AnimNodeLoader.cpp +++ b/libraries/animation/src/AnimNodeLoader.cpp @@ -596,12 +596,15 @@ static AnimNode::Pointer loadSplineIKNode(const QJsonObject& jsonObj, const QStr READ_STRING(enabledVar, jsonObj, id, jsonUrl, nullptr); READ_STRING(endEffectorRotationVarVar, jsonObj, id, jsonUrl, nullptr); READ_STRING(endEffectorPositionVarVar, jsonObj, id, jsonUrl, nullptr); + READ_STRING(primaryFlexCoefficients, jsonObj, id, jsonUrl, nullptr); + READ_STRING(secondaryFlexCoefficients, jsonObj, id, jsonUrl, nullptr); auto node = std::make_shared(id, alpha, enabled, interpDuration, baseJointName, tipJointName, alphaVar, enabledVar, endEffectorRotationVarVar, endEffectorPositionVarVar, basePositionVar, baseRotationVar, - tipPositionVar, tipRotationVar, secondaryTargetJointName, secondaryTargetPositionVar, secondaryTargetRotationVar); + tipPositionVar, tipRotationVar, secondaryTargetJointName, secondaryTargetPositionVar, + secondaryTargetRotationVar, primaryFlexCoefficients, secondaryFlexCoefficients); return node; } diff --git a/libraries/animation/src/AnimSplineIK.cpp b/libraries/animation/src/AnimSplineIK.cpp index bb3ec654f5..658fa2cf6a 100644 --- a/libraries/animation/src/AnimSplineIK.cpp +++ b/libraries/animation/src/AnimSplineIK.cpp @@ -28,7 +28,9 @@ AnimSplineIK::AnimSplineIK(const QString& id, float alpha, bool enabled, float i const QString& tipRotationVar, const QString& secondaryTargetJointName, const QString& secondaryTargetPositionVar, - const QString& secondaryTargetRotationVar) : + const QString& secondaryTargetRotationVar, + const QString& primaryFlexCoefficients, + const QString& secondaryFlexCoefficients) : AnimNode(AnimNode::Type::SplineIK, id), _alpha(alpha), _enabled(enabled), @@ -47,8 +49,25 @@ AnimSplineIK::AnimSplineIK(const QString& id, float alpha, bool enabled, float i _tipRotationVar(tipRotationVar), _secondaryTargetJointName(secondaryTargetJointName), _secondaryTargetPositionVar(secondaryTargetPositionVar), - _secondaryTargetRotationVar(secondaryTargetRotationVar) + _secondaryTargetRotationVar(secondaryTargetRotationVar) { + + QStringList flexCoefficientsValues = primaryFlexCoefficients.split(',', QString::SkipEmptyParts); + for (int i = 0; i < flexCoefficientsValues.size(); i++) { + if (i < MAX_NUMBER_FLEX_VARIABLES) { + qCDebug(animation) << "flex value " << flexCoefficientsValues[i].toDouble(); + _primaryFlexCoefficients[i] = (float)flexCoefficientsValues[i].toDouble(); + } + } + _numPrimaryFlexCoefficients = std::min(flexCoefficientsValues.size(), MAX_NUMBER_FLEX_VARIABLES); + QStringList secondaryFlexCoefficientsValues = secondaryFlexCoefficients.split(',', QString::SkipEmptyParts); + for (int i = 0; i < secondaryFlexCoefficientsValues.size(); i++) { + if (i < MAX_NUMBER_FLEX_VARIABLES) { + qCDebug(animation) << "secondaryflex value " << secondaryFlexCoefficientsValues[i].toDouble(); + _secondaryFlexCoefficients[i] = (float)secondaryFlexCoefficientsValues[i].toDouble(); + } + } + _numSecondaryFlexCoefficients = std::min(secondaryFlexCoefficientsValues.size(), MAX_NUMBER_FLEX_VARIABLES); } @@ -145,8 +164,11 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const target.setPose(rotation, translation); target.setWeight(weight); + + + const float* flexCoefficients = new float[5]{ 1.0f, 0.5f, 0.25f, 0.2f, 0.1f }; - target.setFlexCoefficients(5, flexCoefficients); + target.setFlexCoefficients(_numPrimaryFlexCoefficients, _primaryFlexCoefficients); } AnimChain jointChain; @@ -182,7 +204,7 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const secondaryTarget.setWeight(weight2); const float* flexCoefficients2 = new float[3]{ 1.0f, 0.5f, 0.25f }; - secondaryTarget.setFlexCoefficients(3, flexCoefficients2); + secondaryTarget.setFlexCoefficients(_numSecondaryFlexCoefficients, _secondaryFlexCoefficients); } AnimChain secondaryJointChain; diff --git a/libraries/animation/src/AnimSplineIK.h b/libraries/animation/src/AnimSplineIK.h index d4dbb85a9e..e00b5a5b04 100644 --- a/libraries/animation/src/AnimSplineIK.h +++ b/libraries/animation/src/AnimSplineIK.h @@ -26,7 +26,9 @@ public: const QString& tipPositionVar, const QString& tipRotationVar, const QString& secondaryTargetJointName, const QString& secondaryTargetPositionVar, - const QString& secondaryTargetRotationVar); + const QString& secondaryTargetRotationVar, + const QString& primaryFlexCoefficients, + const QString& secondaryFlexCoefficients); virtual ~AnimSplineIK() override; virtual const AnimPoseVec& evaluate(const AnimVariantMap& animVars, const AnimContext& context, float dt, AnimVariantMap& triggersOut) override; @@ -65,6 +67,14 @@ protected: QString _tipRotationVar; QString _secondaryTargetPositionVar; QString _secondaryTargetRotationVar; + //QString _primaryFlexCoefficients; + //QString _secondaryFlexCoefficients; + + static const int MAX_NUMBER_FLEX_VARIABLES = 10; + float _primaryFlexCoefficients[MAX_NUMBER_FLEX_VARIABLES]; + float _secondaryFlexCoefficients[MAX_NUMBER_FLEX_VARIABLES]; + int _numPrimaryFlexCoefficients { 0 }; + int _numSecondaryFlexCoefficients { 0 }; int _baseParentJointIndex { -1 }; int _baseJointIndex { -1 }; From f2a7f3795084b460a39ae1070cdecc3d89ad2309 Mon Sep 17 00:00:00 2001 From: amantley Date: Fri, 25 Jan 2019 17:11:07 -0800 Subject: [PATCH 021/112] got rid of the lag in the spline code by setting the flex coeffs to 1.0 --- .../avatar/avatar-animation_withIKNode.json | 4 +-- interface/src/Application.cpp | 1 + libraries/animation/src/AnimChain.h | 10 ------ libraries/animation/src/AnimNodeLoader.cpp | 6 ++-- libraries/animation/src/AnimSplineIK.cpp | 31 ++++++------------- libraries/animation/src/AnimSplineIK.h | 4 +-- libraries/animation/src/AnimTwoBoneIK.cpp | 2 +- libraries/animation/src/Rig.cpp | 2 +- libraries/fbx/src/FBXSerializer.cpp | 1 - 9 files changed, 20 insertions(+), 41 deletions(-) diff --git a/interface/resources/avatar/avatar-animation_withIKNode.json b/interface/resources/avatar/avatar-animation_withIKNode.json index 13c102a5f1..bd0baf473e 100644 --- a/interface/resources/avatar/avatar-animation_withIKNode.json +++ b/interface/resources/avatar/avatar-animation_withIKNode.json @@ -194,8 +194,8 @@ "enabledVar": "splineIKEnabled", "endEffectorRotationVarVar": "splineIKRotationVar", "endEffectorPositionVarVar": "splineIKPositionVar", - "primaryFlexCoefficients": "1, 0.5, 0.25, 0.2, 0.1", - "secondaryFlexCoefficients": "1.0, 0.5, 0.25" + "primaryFlexCoefficients": "1.0, 1.0, 1.0, 1.0, 1.0", + "secondaryFlexCoefficients": "1.0, 1.0, 1.0" }, "children": [ { diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index ed1d1a4c99..68ac05ef18 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -4814,6 +4814,7 @@ void setupCpuMonitorThread() { void Application::idle() { PerformanceTimer perfTimer("idle"); + // Update the deadlock watchdog updateHeartbeat(); diff --git a/libraries/animation/src/AnimChain.h b/libraries/animation/src/AnimChain.h index 37d175a334..2385e0c16a 100644 --- a/libraries/animation/src/AnimChain.h +++ b/libraries/animation/src/AnimChain.h @@ -82,16 +82,6 @@ public: return foundIndex; } - const AnimPose& getRelativePoseAtJointIndex(int jointIndex) const { - for (int i = 0; i < _top; i++) { - if (_chain[i].jointIndex == jointIndex) { - return _chain[i].relativePose; - } - } - return AnimPose::identity; - } - - void buildDirtyAbsolutePoses() { // the relative and absolute pose is the same for the base of the chain. _chain[_top - 1].absolutePose = _chain[_top - 1].relativePose; diff --git a/libraries/animation/src/AnimNodeLoader.cpp b/libraries/animation/src/AnimNodeLoader.cpp index c5d17e8884..bce242b50d 100644 --- a/libraries/animation/src/AnimNodeLoader.cpp +++ b/libraries/animation/src/AnimNodeLoader.cpp @@ -601,9 +601,9 @@ static AnimNode::Pointer loadSplineIKNode(const QJsonObject& jsonObj, const QStr auto node = std::make_shared(id, alpha, enabled, interpDuration, baseJointName, tipJointName, - alphaVar, enabledVar, endEffectorRotationVarVar, endEffectorPositionVarVar, - basePositionVar, baseRotationVar, - tipPositionVar, tipRotationVar, secondaryTargetJointName, secondaryTargetPositionVar, + alphaVar, enabledVar, endEffectorRotationVarVar, endEffectorPositionVarVar, + basePositionVar, baseRotationVar, + tipPositionVar, tipRotationVar, secondaryTargetJointName, secondaryTargetPositionVar, secondaryTargetRotationVar, primaryFlexCoefficients, secondaryFlexCoefficients); return node; } diff --git a/libraries/animation/src/AnimSplineIK.cpp b/libraries/animation/src/AnimSplineIK.cpp index 658fa2cf6a..b38850773d 100644 --- a/libraries/animation/src/AnimSplineIK.cpp +++ b/libraries/animation/src/AnimSplineIK.cpp @@ -51,7 +51,7 @@ AnimSplineIK::AnimSplineIK(const QString& id, float alpha, bool enabled, float i _secondaryTargetPositionVar(secondaryTargetPositionVar), _secondaryTargetRotationVar(secondaryTargetRotationVar) { - + QStringList flexCoefficientsValues = primaryFlexCoefficients.split(',', QString::SkipEmptyParts); for (int i = 0; i < flexCoefficientsValues.size(); i++) { if (i < MAX_NUMBER_FLEX_VARIABLES) { @@ -134,7 +134,6 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const glm::vec3 hipsTargetTranslation; // now we override the hips with the hips target pose. - //////////////////////////////////////////////////// if (_poses.size() > 0) { AnimPose hipsUnderPose = _skeleton->getAbsolutePose(_hipsIndex, _poses); hipsTargetRotation = animVars.lookupRigToGeometry("hipsRotation", hipsUnderPose.rot()); @@ -147,12 +146,11 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const _poses[_hipsIndex] = hipsParentAbsPose.inverse() * absHipsTargetPose; _poses[_hipsIndex].scale() = glm::vec3(1.0f); } - ////////////////////////////////////////////////////////////////////////////////// - + AnimPoseVec absolutePoses; absolutePoses.resize(_poses.size()); computeAbsolutePoses(absolutePoses); - + IKTarget target; if (_tipJointIndex != -1) { target.setType((int)IKTarget::Type::Spline); @@ -165,7 +163,7 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const target.setPose(rotation, translation); target.setWeight(weight); - + const float* flexCoefficients = new float[5]{ 1.0f, 0.5f, 0.25f, 0.2f, 0.1f }; target.setFlexCoefficients(_numPrimaryFlexCoefficients, _primaryFlexCoefficients); @@ -186,12 +184,10 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const AnimPose afterSolveSecondaryTarget = _skeleton->getAbsolutePose(_secondaryTargetIndex, _poses); glm::quat secondaryTargetRotation = animVars.lookupRigToGeometry(_secondaryTargetRotationVar, afterSolveSecondaryTarget.rot()); - - updatedSecondaryTarget = AnimPose(secondaryTargetRotation, afterSolveSecondaryTarget.trans()); + updatedSecondaryTarget = AnimPose(secondaryTargetRotation, afterSolveSecondaryTarget.trans()); //updatedSecondaryTarget = AnimPose(afterSolveSecondaryTarget.rot(), afterSolveSecondaryTarget.trans()); } - IKTarget secondaryTarget; computeAbsolutePoses(absolutePoses2); if (_secondaryTargetIndex != -1) { @@ -199,14 +195,13 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const secondaryTarget.setIndex(_secondaryTargetIndex); float weight2 = 1.0f; - secondaryTarget.setPose(updatedSecondaryTarget.rot(), updatedSecondaryTarget.trans()); secondaryTarget.setWeight(weight2); - + const float* flexCoefficients2 = new float[3]{ 1.0f, 0.5f, 0.25f }; secondaryTarget.setFlexCoefficients(_numSecondaryFlexCoefficients, _secondaryFlexCoefficients); } - + AnimChain secondaryJointChain; AnimPose beforeSolveChestNeck; if (_poses.size() > 0) { @@ -223,17 +218,11 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const int tipParent = _skeleton->getParentIndex(_tipJointIndex); int secondaryTargetParent = _skeleton->getParentIndex(_secondaryTargetIndex); if ((secondaryTargetParent != -1) && (tipParent != -1) && (_poses.size() > 0)) { - /* - AnimPose secondaryTargetPose(target2.getRotation(), target2.getTranslation()); - AnimPose secondaryTargetRelativePose = _skeleton->getAbsolutePose(secondaryTargetParent, _poses).inverse() * secondaryTargetPose; - _poses[_secondaryTargetIndex] = secondaryTargetRelativePose; - */ AnimPose secondaryTargetPose(secondaryTarget.getRotation(), secondaryTarget.getTranslation()); AnimPose neckAbsolute = _skeleton->getAbsolutePose(tipParent, _poses); - //AnimPose finalNeckAbsolute = AnimPose(safeLerp(target2.getRotation(), target.getRotation(), 1.0f),neckAbsolute.trans()); _poses[tipParent] = secondaryTargetPose.inverse() * beforeSolveChestNeck; - + AnimPose tipTarget(target.getRotation(),target.getTranslation()); AnimPose tipRelativePose = _skeleton->getAbsolutePose(tipParent,_poses).inverse() * tipTarget; _poses[_tipJointIndex] = tipRelativePose; @@ -314,7 +303,7 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const } _previousEnableDebugIKTargets = context.getEnableDebugDrawIKTargets(); - + return _poses; } @@ -458,7 +447,7 @@ void AnimSplineIK::solveTargetWithSpline(const AnimContext& context, const IKTar relPose.trans() = glm::vec3(0.0f); } } - // note we are ignoring the constrained info for now. + // note we are ignoring the constrained info for now. if (!chainInfoOut.setRelativePoseAtJointIndex(splineJointInfo.jointIndex, relPose)) { qCDebug(animation) << "we didn't find the joint index for the spline!!!!"; } diff --git a/libraries/animation/src/AnimSplineIK.h b/libraries/animation/src/AnimSplineIK.h index e00b5a5b04..c6d435fd6b 100644 --- a/libraries/animation/src/AnimSplineIK.h +++ b/libraries/animation/src/AnimSplineIK.h @@ -21,8 +21,8 @@ public: AnimSplineIK(const QString& id, float alpha, bool enabled, float interpDuration, const QString& baseJointName, const QString& tipJointName, const QString& alphaVar, const QString& enabledVar, - const QString& endEffectorRotationVarVar, const QString& endEffectorPositionVarVar, - const QString& basePositionVar, const QString& baseRotationVar, + const QString& endEffectorRotationVarVar, const QString& endEffectorPositionVarVar, + const QString& basePositionVar, const QString& baseRotationVar, const QString& tipPositionVar, const QString& tipRotationVar, const QString& secondaryTargetJointName, const QString& secondaryTargetPositionVar, diff --git a/libraries/animation/src/AnimTwoBoneIK.cpp b/libraries/animation/src/AnimTwoBoneIK.cpp index 3f8de488ff..8960b15940 100644 --- a/libraries/animation/src/AnimTwoBoneIK.cpp +++ b/libraries/animation/src/AnimTwoBoneIK.cpp @@ -89,7 +89,7 @@ const AnimPoseVec& AnimTwoBoneIK::evaluate(const AnimVariantMap& animVars, const } _enabled = enabled; - // don't build chains or do IK if we are disabled & not interping. + // don't build chains or do IK if we are disbled & not interping. if (_interpType == InterpType::None && !enabled) { _poses = underPoses; return _poses; diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index 93daeda4d9..713f9bc385 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -1468,7 +1468,7 @@ void Rig::updateHands(bool leftHandEnabled, bool rightHandEnabled, bool hipsEnab // need this for two bone ik _animVars.set(LEFT_HAND_IK_POSITION_VAR, MAIN_STATE_MACHINE_LEFT_HAND_POSITION); _animVars.set(LEFT_HAND_IK_ROTATION_VAR, MAIN_STATE_MACHINE_LEFT_HAND_ROTATION); - + _animVars.set("leftHandPoleVectorEnabled", false); _animVars.unset("leftHandPosition"); _animVars.unset("leftHandRotation"); diff --git a/libraries/fbx/src/FBXSerializer.cpp b/libraries/fbx/src/FBXSerializer.cpp index 2c13be534a..4c82b4f5d7 100644 --- a/libraries/fbx/src/FBXSerializer.cpp +++ b/libraries/fbx/src/FBXSerializer.cpp @@ -1314,7 +1314,6 @@ HFMModel* FBXSerializer::extractHFMModel(const QVariantHash& mapping, const QStr joint.inverseBindRotation = joint.inverseDefaultRotation; joint.name = fbxModel.name; if (hfmModel.hfmToHifiJointNameMapping.contains(hfmModel.hfmToHifiJointNameMapping.key(joint.name))) { - // qCDebug(modelformat) << "joint name " << joint.name << " hifi name " << hfmModel.hfmToHifiJointNameMapping.key(fbxModel.name); joint.name = hfmModel.hfmToHifiJointNameMapping.key(fbxModel.name); } From 0b6d0b4bafaab5ea6e61f5bbefba7440efb03c3f Mon Sep 17 00:00:00 2001 From: amantley Date: Fri, 25 Jan 2019 18:17:15 -0800 Subject: [PATCH 022/112] renamed json to reflect spline node --- .../avatar/avatar-animation_twoboneIK.json | 2204 ----------------- ...=> avatar-animation_withSplineIKNode.json} | 0 2 files changed, 2204 deletions(-) delete mode 100644 interface/resources/avatar/avatar-animation_twoboneIK.json rename interface/resources/avatar/{avatar-animation_withIKNode.json => avatar-animation_withSplineIKNode.json} (100%) diff --git a/interface/resources/avatar/avatar-animation_twoboneIK.json b/interface/resources/avatar/avatar-animation_twoboneIK.json deleted file mode 100644 index 45cb7b570e..0000000000 --- a/interface/resources/avatar/avatar-animation_twoboneIK.json +++ /dev/null @@ -1,2204 +0,0 @@ -{ - "version": "1.1", - "root": { - "id": "userAnimStateMachine", - "type": "stateMachine", - "data": { - "currentState": "userAnimNone", - "states": [ - { - "id": "userAnimNone", - "interpTarget": 6, - "interpDuration": 6, - "transitions": [ - { "var": "userAnimA", "state": "userAnimA" }, - { "var": "userAnimB", "state": "userAnimB" } - ] - }, - { - "id": "userAnimA", - "interpTarget": 6, - "interpDuration": 6, - "transitions": [ - { "var": "userAnimNone", "state": "userAnimNone" }, - { "var": "userAnimB", "state": "userAnimB" } - ] - }, - { - "id": "userAnimB", - "interpTarget": 6, - "interpDuration": 6, - "transitions": [ - { "var": "userAnimNone", "state": "userAnimNone" }, - { "var": "userAnimA", "state": "userAnimA" } - ] - } - ] - }, - "children": [ - { - "id": "userAnimNone", - "type": "splineIK", - "data": { - "alpha": 1.0, - "enabled": false, - "interpDuration": 15, - "baseJointName": "Hips", - "tipJointName": "Head", - "alphaVar": "splineIKAlpha", - "enabledVar": "splineIKEnabled", - "endEffectorRotationVarVar": "splineIKRotationVar", - "endEffectorPositionVarVar": "splineIKPositionVar" - }, - "children": [ - { - "id": "rightFootPoleVector", - "type": "poleVectorConstraint", - "data": { - "enabled": false, - "referenceVector": [ 0, 0, 1 ], - "baseJointName": "RightUpLeg", - "midJointName": "RightLeg", - "tipJointName": "RightFoot", - "enabledVar": "rightFootPoleVectorEnabled", - "poleVectorVar": "rightFootPoleVector" - }, - "children": [ - { - "id": "rightFootIK", - "type": "twoBoneIK", - "data": { - "alpha": 1.0, - "enabled": false, - "interpDuration": 15, - "baseJointName": "RightUpLeg", - "midJointName": "RightLeg", - "tipJointName": "RightFoot", - "midHingeAxis": [ -1, 0, 0 ], - "alphaVar": "rightFootIKAlpha", - "enabledVar": "rightFootIKEnabled", - "endEffectorRotationVarVar": "rightFootIKRotationVar", - "endEffectorPositionVarVar": "rightFootIKPositionVar" - }, - "children": [ - { - "id": "leftFootPoleVector", - "type": "poleVectorConstraint", - "data": { - "enabled": false, - "referenceVector": [ 0, 0, 1 ], - "baseJointName": "LeftUpLeg", - "midJointName": "LeftLeg", - "tipJointName": "LeftFoot", - "enabledVar": "leftFootPoleVectorEnabled", - "poleVectorVar": "leftFootPoleVector" - }, - "children": [ - { - "id": "leftFootIK", - "type": "twoBoneIK", - "data": { - "alpha": 1.0, - "enabled": false, - "interpDuration": 15, - "baseJointName": "LeftUpLeg", - "midJointName": "LeftLeg", - "tipJointName": "LeftFoot", - "midHingeAxis": [ -1, 0, 0 ], - "alphaVar": "leftFootIKAlpha", - "enabledVar": "leftFootIKEnabled", - "endEffectorRotationVarVar": "leftFootIKRotationVar", - "endEffectorPositionVarVar": "leftFootIKPositionVar" - }, - "children": [ - { - "id": "rightHandPoleVector", - "type": "poleVectorConstraint", - "data": { - "enabled": false, - "referenceVector": [ 0, 0, 1 ], - "baseJointName": "RightArm", - "midJointName": "RightForeArm", - "tipJointName": "RightHand", - "enabledVar": "rightHandPoleVectorEnabled", - "poleVectorVar": "rightHandPoleVector" - }, - "children": [ - { - "id": "rightHandIK", - "type": "twoBoneIK", - "data": { - "alpha": 1.0, - "enabled": false, - "interpDuration": 15, - "baseJointName": "RightArm", - "midJointName": "RightForeArm", - "tipJointName": "RightHand", - "midHingeAxis": [ 0, 0, -1 ], - "alphaVar": "rightHandIKAlpha", - "enabledVar": "rightHandIKEnabled", - "endEffectorRotationVarVar": "rightHandIKRotationVar", - "endEffectorPositionVarVar": "rightHandIKPositionVar" - }, - "children": [ - { - "id": "leftHandPoleVector", - "type": "poleVectorConstraint", - "data": { - "enabled": false, - "referenceVector": [ 0, 0, 1 ], - "baseJointName": "LeftArm", - "midJointName": "LeftForeArm", - "tipJointName": "LeftHand", - "enabledVar": "leftHandPoleVectorEnabled", - "poleVectorVar": "leftHandPoleVector" - }, - "children": [ - { - "id": "leftHandIK", - "type": "twoBoneIK", - "data": { - "alpha": 1.0, - "enabled": false, - "interpDuration": 15, - "baseJointName": "LeftArm", - "midJointName": "LeftForeArm", - "tipJointName": "LeftHand", - "midHingeAxis": [ 0, 0, 1 ], - "alphaVar": "leftHandIKAlpha", - "enabledVar": "leftHandIKEnabled", - "endEffectorRotationVarVar": "leftHandIKRotationVar", - "endEffectorPositionVarVar": "leftHandIKPositionVar" - }, - "children": [ - { - "id": "defaultPoseOverlay", - "type": "overlay", - "data": { - "alpha": 0.0, - "alphaVar": "defaultPoseOverlayAlpha", - "boneSet": "fullBody", - "boneSetVar": "defaultPoseOverlayBoneSet" - }, - "children": [ - { - "id": "defaultPose", - "type": "defaultPose", - "data": { - }, - "children": [] - }, - { - "id": "rightHandOverlay", - "type": "overlay", - "data": { - "alpha": 0.0, - "boneSet": "rightHand", - "alphaVar": "rightHandOverlayAlpha" - }, - "children": [ - { - "id": "rightHandStateMachine", - "type": "stateMachine", - "data": { - "currentState": "rightHandGrasp", - "states": [ - { - "id": "rightHandGrasp", - "interpTarget": 3, - "interpDuration": 3, - "transitions": [ - { - "var": "isRightIndexPoint", - "state": "rightIndexPoint" - }, - { - "var": "isRightThumbRaise", - "state": "rightThumbRaise" - }, - { - "var": "isRightIndexPointAndThumbRaise", - "state": "rightIndexPointAndThumbRaise" - } - ] - }, - { - "id": "rightIndexPoint", - "interpTarget": 15, - "interpDuration": 3, - "transitions": [ - { - "var": "isRightHandGrasp", - "state": "rightHandGrasp" - }, - { - "var": "isRightThumbRaise", - "state": "rightThumbRaise" - }, - { - "var": "isRightIndexPointAndThumbRaise", - "state": "rightIndexPointAndThumbRaise" - } - ] - }, - { - "id": "rightThumbRaise", - "interpTarget": 15, - "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" - } - ] - } - ] - }, - "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", - "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": "mainStateMachine", - "type": "stateMachine", - "data": { - "outputJoints": [ "LeftFoot", "RightFoot" ], - "currentState": "idle", - "states": [ - { - "id": "idle", - "interpTarget": 20, - "interpDuration": 8, - "interpType": "snapshotPrev", - "transitions": [ - { - "var": "isMovingForward", - "state": "WALKFWD" - }, - { - "var": "isMovingBackward", - "state": "WALKBWD" - }, - { - "var": "isMovingRight", - "state": "STRAFERIGHT" - }, - { - "var": "isMovingLeft", - "state": "STRAFELEFT" - }, - { - "var": "isTurningRight", - "state": "turnRight" - }, - { - "var": "isTurningLeft", - "state": "turnLeft" - }, - { - "var": "isFlying", - "state": "fly" - }, - { - "var": "isTakeoffStand", - "state": "takeoffStand" - }, - { - "var": "isTakeoffRun", - "state": "TAKEOFFRUN" - }, - { - "var": "isInAirStand", - "state": "inAirStand" - }, - { - "var": "isInAirRun", - "state": "INAIRRUN" - }, - { - "var": "isMovingRightHmd", - "state": "strafeRightHmd" - }, - { - "var": "isMovingLeftHmd", - "state": "strafeLeftHmd" - } - ] - }, - { - "id": "idleToWalkFwd", - "interpTarget": 12, - "interpDuration": 8, - "transitions": [ - { - "var": "idleToWalkFwdOnDone", - "state": "WALKFWD" - }, - { - "var": "isNotMoving", - "state": "idle" - }, - { - "var": "isMovingBackward", - "state": "WALKBWD" - }, - { - "var": "isMovingRight", - "state": "STRAFERIGHT" - }, - { - "var": "isMovingLeft", - "state": "STRAFELEFT" - }, - { - "var": "isTurningRight", - "state": "turnRight" - }, - { - "var": "isTurningLeft", - "state": "turnLeft" - }, - { - "var": "isFlying", - "state": "fly" - }, - { - "var": "isTakeoffStand", - "state": "takeoffStand" - }, - { - "var": "isTakeoffRun", - "state": "TAKEOFFRUN" - }, - { - "var": "isInAirStand", - "state": "inAirStand" - }, - { - "var": "isInAirRun", - "state": "INAIRRUN" - }, - { - "var": "isMovingRightHmd", - "state": "strafeRightHmd" - }, - { - "var": "isMovingLeftHmd", - "state": "strafeLeftHmd" - } - ] - }, - { - "id": "idleSettle", - "interpTarget": 15, - "interpDuration": 8, - "interpType": "snapshotPrev", - "transitions": [ - { - "var": "idleSettleOnDone", - "state": "idle" - }, - { - "var": "isMovingForward", - "state": "WALKFWD" - }, - { - "var": "isMovingBackward", - "state": "WALKBWD" - }, - { - "var": "isMovingRight", - "state": "STRAFERIGHT" - }, - { - "var": "isMovingLeft", - "state": "STRAFELEFT" - }, - { - "var": "isMovingRightHmd", - "state": "strafeRightHmd" - }, - { - "var": "isMovingLeftHmd", - "state": "strafeLeftHmd" - }, - { - "var": "isTurningRight", - "state": "turnRight" - }, - { - "var": "isTurningLeft", - "state": "turnLeft" - }, - { - "var": "isFlying", - "state": "fly" - }, - { - "var": "isTakeoffStand", - "state": "takeoffStand" - }, - { - "var": "isTakeoffRun", - "state": "TAKEOFFRUN" - }, - { - "var": "isInAirStand", - "state": "inAirStand" - }, - { - "var": "isInAirRun", - "state": "INAIRRUN" - } - ] - }, - { - "id": "WALKFWD", - "interpTarget": 35, - "interpDuration": 10, - "interpType": "snapshotPrev", - "transitions": [ - { - "var": "isNotMoving", - "state": "idleSettle" - }, - { - "var": "isMovingBackward", - "state": "WALKBWD" - }, - { - "var": "isMovingRight", - "state": "STRAFERIGHT" - }, - { - "var": "isMovingLeft", - "state": "STRAFELEFT" - }, - { - "var": "isTurningRight", - "state": "turnRight" - }, - { - "var": "isTurningLeft", - "state": "turnLeft" - }, - { - "var": "isFlying", - "state": "fly" - }, - { - "var": "isTakeoffStand", - "state": "takeoffStand" - }, - { - "var": "isTakeoffRun", - "state": "TAKEOFFRUN" - }, - { - "var": "isInAirStand", - "state": "inAirStand" - }, - { - "var": "isInAirRun", - "state": "INAIRRUN" - }, - { - "var": "isMovingRightHmd", - "state": "strafeRightHmd" - }, - { - "var": "isMovingLeftHmd", - "state": "strafeLeftHmd" - } - ] - }, - { - "id": "WALKBWD", - "interpTarget": 35, - "interpDuration": 10, - "interpType": "snapshotPrev", - "transitions": [ - { - "var": "isNotMoving", - "state": "idleSettle" - }, - { - "var": "isMovingForward", - "state": "WALKFWD" - }, - { - "var": "isMovingRight", - "state": "STRAFERIGHT" - }, - { - "var": "isMovingLeft", - "state": "STRAFELEFT" - }, - { - "var": "isTurningRight", - "state": "turnRight" - }, - { - "var": "isTurningLeft", - "state": "turnLeft" - }, - { - "var": "isFlying", - "state": "fly" - }, - { - "var": "isTakeoffStand", - "state": "takeoffStand" - }, - { - "var": "isTakeoffRun", - "state": "TAKEOFFRUN" - }, - { - "var": "isInAirStand", - "state": "inAirStand" - }, - { - "var": "isInAirRun", - "state": "INAIRRUN" - }, - { - "var": "isMovingRightHmd", - "state": "strafeRightHmd" - }, - { - "var": "isMovingLeftHmd", - "state": "strafeLeftHmd" - } - ] - }, - { - "id": "STRAFERIGHT", - "interpTarget": 25, - "interpDuration": 8, - "interpType": "snapshotPrev", - "transitions": [ - { - "var": "isNotMoving", - "state": "idleSettle" - }, - { - "var": "isMovingForward", - "state": "WALKFWD" - }, - { - "var": "isMovingBackward", - "state": "WALKBWD" - }, - { - "var": "isMovingLeft", - "state": "STRAFELEFT" - }, - { - "var": "isTurningRight", - "state": "turnRight" - }, - { - "var": "isTurningLeft", - "state": "turnLeft" - }, - { - "var": "isFlying", - "state": "fly" - }, - { - "var": "isTakeoffStand", - "state": "takeoffStand" - }, - { - "var": "isTakeoffRun", - "state": "TAKEOFFRUN" - }, - { - "var": "isInAirStand", - "state": "inAirStand" - }, - { - "var": "isInAirRun", - "state": "INAIRRUN" - }, - { - "var": "isMovingRightHmd", - "state": "strafeRightHmd" - }, - { - "var": "isMovingLeftHmd", - "state": "strafeLeftHmd" - } - ] - }, - { - "id": "STRAFELEFT", - "interpTarget": 25, - "interpDuration": 8, - "interpType": "snapshotPrev", - "transitions": [ - { - "var": "isNotMoving", - "state": "idleSettle" - }, - { - "var": "isMovingForward", - "state": "WALKFWD" - }, - { - "var": "isMovingBackward", - "state": "WALKBWD" - }, - { - "var": "isMovingRight", - "state": "STRAFERIGHT" - }, - { - "var": "isTurningRight", - "state": "turnRight" - }, - { - "var": "isTurningLeft", - "state": "turnLeft" - }, - { - "var": "isFlying", - "state": "fly" - }, - { - "var": "isTakeoffStand", - "state": "takeoffStand" - }, - { - "var": "isTakeoffRun", - "state": "TAKEOFFRUN" - }, - { - "var": "isInAirStand", - "state": "inAirStand" - }, - { - "var": "isInAirRun", - "state": "INAIRRUN" - }, - { - "var": "isMovingRightHmd", - "state": "strafeRightHmd" - }, - { - "var": "isMovingLeftHmd", - "state": "strafeLeftHmd" - } - ] - }, - { - "id": "turnRight", - "interpTarget": 6, - "interpDuration": 8, - "transitions": [ - { - "var": "isNotTurning", - "state": "idle" - }, - { - "var": "isMovingForward", - "state": "WALKFWD" - }, - { - "var": "isMovingBackward", - "state": "WALKBWD" - }, - { - "var": "isMovingRight", - "state": "STRAFERIGHT" - }, - { - "var": "isMovingLeft", - "state": "STRAFELEFT" - }, - { - "var": "isTurningLeft", - "state": "turnLeft" - }, - { - "var": "isFlying", - "state": "fly" - }, - { - "var": "isTakeoffStand", - "state": "takeoffStand" - }, - { - "var": "isTakeoffRun", - "state": "TAKEOFFRUN" - }, - { - "var": "isInAirStand", - "state": "inAirStand" - }, - { - "var": "isInAirRun", - "state": "INAIRRUN" - }, - { - "var": "isMovingRightHmd", - "state": "strafeRightHmd" - }, - { - "var": "isMovingLeftHmd", - "state": "strafeLeftHmd" - } - ] - }, - { - "id": "turnLeft", - "interpTarget": 6, - "interpDuration": 8, - "transitions": [ - { - "var": "isNotTurning", - "state": "idle" - }, - { - "var": "isMovingForward", - "state": "WALKFWD" - }, - { - "var": "isMovingBackward", - "state": "WALKBWD" - }, - { - "var": "isMovingRight", - "state": "STRAFERIGHT" - }, - { - "var": "isMovingLeft", - "state": "STRAFELEFT" - }, - { - "var": "isTurningRight", - "state": "turnRight" - }, - { - "var": "isFlying", - "state": "fly" - }, - { - "var": "isTakeoffStand", - "state": "takeoffStand" - }, - { - "var": "isTakeoffRun", - "state": "TAKEOFFRUN" - }, - { - "var": "isInAirStand", - "state": "inAirStand" - }, - { - "var": "isInAirRun", - "state": "INAIRRUN" - }, - { - "var": "isMovingRightHmd", - "state": "strafeRightHmd" - }, - { - "var": "isMovingLeftHmd", - "state": "strafeLeftHmd" - } - ] - }, - { - "id": "strafeRightHmd", - "interpTarget": 5, - "interpDuration": 8, - "interpType": "snapshotPrev", - "transitions": [ - { - "var": "isNotMoving", - "state": "idleSettle" - }, - { - "var": "isMovingForward", - "state": "WALKFWD" - }, - { - "var": "isMovingBackward", - "state": "WALKBWD" - }, - { - "var": "isMovingLeftHmd", - "state": "strafeLeftHmd" - }, - { - "var": "isMovingRight", - "state": "STRAFERIGHT" - }, - { - "var": "isMovingLeft", - "state": "STRAFELEFT" - }, - { - "var": "isTurningRight", - "state": "turnRight" - }, - { - "var": "isTurningLeft", - "state": "turnLeft" - }, - { - "var": "isFlying", - "state": "fly" - }, - { - "var": "isTakeoffStand", - "state": "takeoffStand" - }, - { - "var": "isTakeoffRun", - "state": "TAKEOFFRUN" - }, - { - "var": "isInAirStand", - "state": "inAirStand" - }, - { - "var": "isInAirRun", - "state": "INAIRRUN" - } - ] - }, - { - "id": "strafeLeftHmd", - "interpTarget": 5, - "interpDuration": 8, - "interpType": "snapshotPrev", - "transitions": [ - { - "var": "isNotMoving", - "state": "idleSettle" - }, - { - "var": "isMovingForward", - "state": "WALKFWD" - }, - { - "var": "isMovingBackward", - "state": "WALKBWD" - }, - { - "var": "isMovingRightHmd", - "state": "strafeRightHmd" - }, - { - "var": "isMovingRight", - "state": "STRAFERIGHT" - }, - { - "var": "isMovingLeft", - "state": "STRAFELEFT" - }, - { - "var": "isTurningRight", - "state": "turnRight" - }, - { - "var": "isTurningLeft", - "state": "turnLeft" - }, - { - "var": "isFlying", - "state": "fly" - }, - { - "var": "isTakeoffStand", - "state": "takeoffStand" - }, - { - "var": "isTakeoffRun", - "state": "TAKEOFFRUN" - }, - { - "var": "isInAirStand", - "state": "inAirStand" - }, - { - "var": "isInAirRun", - "state": "INAIRRUN" - } - ] - }, - { - "id": "fly", - "interpTarget": 6, - "interpDuration": 6, - "transitions": [ - { - "var": "isNotFlying", - "state": "idleSettle" - } - ] - }, - { - "id": "takeoffStand", - "interpTarget": 2, - "interpDuration": 2, - "transitions": [ - { - "var": "isNotTakeoff", - "state": "inAirStand" - } - ] - }, - { - "id": "TAKEOFFRUN", - "interpTarget": 2, - "interpDuration": 2, - "transitions": [ - { - "var": "isNotTakeoff", - "state": "INAIRRUN" - } - ] - }, - { - "id": "inAirStand", - "interpTarget": 3, - "interpDuration": 3, - "interpType": "snapshotPrev", - "transitions": [ - { - "var": "isNotInAir", - "state": "landStandImpact" - } - ] - }, - { - "id": "INAIRRUN", - "interpTarget": 3, - "interpDuration": 3, - "interpType": "snapshotPrev", - "transitions": [ - { - "var": "isNotInAir", - "state": "WALKFWD" - } - ] - }, - { - "id": "landStandImpact", - "interpTarget": 1, - "interpDuration": 1, - "transitions": [ - { - "var": "isFlying", - "state": "fly" - }, - { - "var": "isTakeoffStand", - "state": "takeoffStand" - }, - { - "var": "isTakeoffRun", - "state": "TAKEOFFRUN" - }, - { - "var": "landStandImpactOnDone", - "state": "landStand" - } - ] - }, - { - "id": "landStand", - "interpTarget": 1, - "interpDuration": 1, - "transitions": [ - { - "var": "isMovingForward", - "state": "WALKFWD" - }, - { - "var": "isMovingBackward", - "state": "WALKBWD" - }, - { - "var": "isMovingRight", - "state": "STRAFERIGHT" - }, - { - "var": "isMovingLeft", - "state": "STRAFELEFT" - }, - { - "var": "isTurningRight", - "state": "turnRight" - }, - { - "var": "isTurningLeft", - "state": "turnLeft" - }, - { - "var": "isFlying", - "state": "fly" - }, - { - "var": "isTakeoffStand", - "state": "takeoffStand" - }, - { - "var": "isTakeoffRun", - "state": "TAKEOFFRUN" - }, - { - "var": "isInAirStand", - "state": "inAirStand" - }, - { - "var": "isInAirRun", - "state": "INAIRRUN" - }, - { - "var": "landStandOnDone", - "state": "idle" - }, - { - "var": "isMovingRightHmd", - "state": "strafeRightHmd" - }, - { - "var": "isMovingLeftHmd", - "state": "strafeLeftHmd" - } - ] - }, - { - "id": "LANDRUN", - "interpTarget": 2, - "interpDuration": 2, - "transitions": [ - { - "var": "isFlying", - "state": "fly" - }, - { - "var": "isTakeoffStand", - "state": "takeoffStand" - }, - { - "var": "isTakeoffRun", - "state": "TAKEOFFRUN" - }, - { - "var": "landRunOnDone", - "state": "WALKFWD" - } - ] - } - ] - }, - "children": [ - { - "id": "idle", - "type": "stateMachine", - "data": { - "currentState": "idleStand", - "states": [ - { - "id": "idleStand", - "interpTarget": 6, - "interpDuration": 10, - "transitions": [ - { - "var": "isTalking", - "state": "idleTalk" - } - ] - }, - { - "id": "idleTalk", - "interpTarget": 6, - "interpDuration": 10, - "transitions": [ - { - "var": "notIsTalking", - "state": "idleStand" - } - ] - } - ] - }, - "children": [ - { - "id": "idleStand", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/idle.fbx", - "startFrame": 0.0, - "endFrame": 300.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - }, - { - "id": "idleTalk", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/talk.fbx", - "startFrame": 0.0, - "endFrame": 800.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - } - ] - }, - { - "id": "WALKFWD", - "type": "blendLinearMove", - "data": { - "alpha": 0.0, - "desiredSpeed": 1.4, - "characteristicSpeeds": [ 0.5, 1.8, 2.3, 3.2, 4.5 ], - "alphaVar": "moveForwardAlpha", - "desiredSpeedVar": "moveForwardSpeed" - }, - "children": [ - { - "id": "walkFwdShort_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/walk_short_fwd.fbx", - "startFrame": 0.0, - "endFrame": 39.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - }, - { - "id": "walkFwdNormal_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/walk_fwd.fbx", - "startFrame": 0.0, - "endFrame": 30.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - }, - { - "id": "walkFwdFast_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/walk_fwd_fast.fbx", - "startFrame": 0.0, - "endFrame": 25.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - }, - { - "id": "walkFwdJog_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/jog_fwd.fbx", - "startFrame": 0.0, - "endFrame": 25.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - }, - { - "id": "walkFwdRun_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/run_fwd.fbx", - "startFrame": 0.0, - "endFrame": 21.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - } - ] - }, - { - "id": "idleToWalkFwd", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/idle_to_walk.fbx", - "startFrame": 1.0, - "endFrame": 13.0, - "timeScale": 1.0, - "loopFlag": false - }, - "children": [] - }, - { - "id": "idleSettle", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/settle_to_idle.fbx", - "startFrame": 1.0, - "endFrame": 59.0, - "timeScale": 1.0, - "loopFlag": false - }, - "children": [] - }, - { - "id": "WALKBWD", - "type": "blendLinearMove", - "data": { - "alpha": 0.0, - "desiredSpeed": 1.4, - "characteristicSpeeds": [ 0.6, 1.6, 2.3, 3.1 ], - "alphaVar": "moveBackwardAlpha", - "desiredSpeedVar": "moveBackwardSpeed" - }, - "children": [ - { - "id": "walkBwdShort_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/walk_short_bwd.fbx", - "startFrame": 0.0, - "endFrame": 38.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - }, - { - "id": "walkBwdFast_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/walk_bwd_fast.fbx", - "startFrame": 0.0, - "endFrame": 27.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - }, - { - "id": "jogBwd_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/jog_bwd.fbx", - "startFrame": 0.0, - "endFrame": 24.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - }, - { - "id": "runBwd_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/run_bwd.fbx", - "startFrame": 0.0, - "endFrame": 16.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - } - ] - }, - { - "id": "turnLeft", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/turn_left.fbx", - "startFrame": 0.0, - "endFrame": 32.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - }, - { - "id": "turnRight", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/turn_left.fbx", - "startFrame": 0.0, - "endFrame": 32.0, - "timeScale": 1.0, - "loopFlag": true, - "mirrorFlag": true - }, - "children": [] - }, - { - "id": "STRAFELEFT", - "type": "blendLinearMove", - "data": { - "alpha": 0.0, - "desiredSpeed": 1.4, - "characteristicSpeeds": [ 0.1, 0.5, 1.0, 2.6, 3.0 ], - "alphaVar": "moveLateralAlpha", - "desiredSpeedVar": "moveLateralSpeed" - }, - "children": [ - { - "id": "strafeLeftShortStep_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/side_step_short_left.fbx", - "startFrame": 0.0, - "endFrame": 29.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - }, - { - "id": "strafeLeftStep_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/side_step_left.fbx", - "startFrame": 0.0, - "endFrame": 20.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - }, - { - "id": "strafeLeftWalk_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/walk_left.fbx", - "startFrame": 0.0, - "endFrame": 35.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - }, - { - "id": "strafeLeftWalkFast_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/walk_left_fast.fbx", - "startFrame": 0.0, - "endFrame": 21.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - }, - { - "id": "strafeLeftJog_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/jog_left.fbx", - "startFrame": 0.0, - "endFrame": 24.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - } - ] - }, - { - "id": "STRAFERIGHT", - "type": "blendLinearMove", - "data": { - "alpha": 0.0, - "desiredSpeed": 1.4, - "characteristicSpeeds": [ 0.1, 0.5, 1.0, 2.6, 3.0 ], - "alphaVar": "moveLateralAlpha", - "desiredSpeedVar": "moveLateralSpeed" - }, - "children": [ - { - "id": "strafeRightShortStep_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/side_step_short_left.fbx", - "startFrame": 0.0, - "endFrame": 29.0, - "timeScale": 1.0, - "loopFlag": true, - "mirrorFlag": true - }, - "children": [] - }, - { - "id": "strafeRightStep_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/side_step_left.fbx", - "startFrame": 0.0, - "endFrame": 20.0, - "timeScale": 1.0, - "loopFlag": true, - "mirrorFlag": true - }, - "children": [] - }, - { - "id": "strafeRightWalk_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/walk_left.fbx", - "startFrame": 0.0, - "endFrame": 35.0, - "timeScale": 1.0, - "loopFlag": true, - "mirrorFlag": true - }, - "children": [] - }, - { - "id": "strafeRightFast_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/walk_left_fast.fbx", - "startFrame": 0.0, - "endFrame": 21.0, - "timeScale": 1.0, - "loopFlag": true, - "mirrorFlag": true - }, - "children": [] - }, - { - "id": "strafeRightJog_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/jog_left.fbx", - "startFrame": 0.0, - "endFrame": 24.0, - "timeScale": 1.0, - "loopFlag": true, - "mirrorFlag": true - }, - "children": [] - } - ] - }, - { - "id": "strafeLeftHmd", - "type": "blendLinearMove", - "data": { - "alpha": 0.0, - "desiredSpeed": 1.4, - "characteristicSpeeds": [ 0, 0.5, 2.5 ], - "alphaVar": "moveLateralAlpha", - "desiredSpeedVar": "moveLateralSpeed" - }, - "children": [ - { - "id": "stepLeftShort_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/side_step_short_left.fbx", - "startFrame": 0.0, - "endFrame": 29.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - }, - { - "id": "stepLeft_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/side_step_left.fbx", - "startFrame": 0.0, - "endFrame": 20.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - }, - { - "id": "strafeLeftAnim_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/side_step_left_fast.fbx", - "startFrame": 0.0, - "endFrame": 16.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - } - ] - }, - { - "id": "strafeRightHmd", - "type": "blendLinearMove", - "data": { - "alpha": 0.0, - "desiredSpeed": 1.4, - "characteristicSpeeds": [ 0, 0.5, 2.5 ], - "alphaVar": "moveLateralAlpha", - "desiredSpeedVar": "moveLateralSpeed" - }, - "children": [ - { - "id": "stepRightShort_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/side_step_short_left.fbx", - "startFrame": 0.0, - "endFrame": 29.0, - "timeScale": 1.0, - "loopFlag": true, - "mirrorFlag": true - }, - "children": [] - }, - { - "id": "stepRight_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/side_step_left.fbx", - "startFrame": 0.0, - "endFrame": 20.0, - "timeScale": 1.0, - "loopFlag": true, - "mirrorFlag": true - }, - "children": [] - }, - { - "id": "strafeRightAnim_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/side_step_left_fast.fbx", - "startFrame": 0.0, - "endFrame": 16.0, - "timeScale": 1.0, - "loopFlag": true, - "mirrorFlag": true - }, - "children": [] - } - ] - }, - { - "id": "fly", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/fly.fbx", - "startFrame": 1.0, - "endFrame": 80.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - }, - { - "id": "takeoffStand", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/jump_standing_launch.fbx", - "startFrame": 2.0, - "endFrame": 16.0, - "timeScale": 1.0, - "loopFlag": false - }, - "children": [] - }, - { - "id": "TAKEOFFRUN", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/jump_running_launch_land.fbx", - "startFrame": 4.0, - "endFrame": 15.0, - "timeScale": 1.0, - "loopFlag": false - }, - "children": [] - }, - { - "id": "inAirStand", - "type": "blendLinear", - "data": { - "alpha": 0.0, - "alphaVar": "inAirAlpha" - }, - "children": [ - { - "id": "inAirStandPreApex", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/jump_standing_apex.fbx", - "startFrame": 0.0, - "endFrame": 0.0, - "timeScale": 1.0, - "loopFlag": false - }, - "children": [] - }, - { - "id": "inAirStandApex", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/jump_standing_apex.fbx", - "startFrame": 1.0, - "endFrame": 1.0, - "timeScale": 1.0, - "loopFlag": false - }, - "children": [] - }, - { - "id": "inAirStandPostApex", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/jump_standing_apex.fbx", - "startFrame": 2.0, - "endFrame": 2.0, - "timeScale": 1.0, - "loopFlag": false - }, - "children": [] - } - ] - }, - { - "id": "INAIRRUN", - "type": "blendLinear", - "data": { - "alpha": 0.0, - "alphaVar": "inAirAlpha" - }, - "children": [ - { - "id": "inAirRunPreApex", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/jump_running_launch_land.fbx", - "startFrame": 16.0, - "endFrame": 16.0, - "timeScale": 1.0, - "loopFlag": false - }, - "children": [] - }, - { - "id": "inAirRunApex", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/jump_running_launch_land.fbx", - "startFrame": 22.0, - "endFrame": 22.0, - "timeScale": 1.0, - "loopFlag": false - }, - "children": [] - }, - { - "id": "inAirRunPostApex", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/jump_running_launch_land.fbx", - "startFrame": 33.0, - "endFrame": 33.0, - "timeScale": 1.0, - "loopFlag": false - }, - "children": [] - } - ] - }, - { - "id": "landStandImpact", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/jump_standing_land_settle.fbx", - "startFrame": 1.0, - "endFrame": 6.0, - "timeScale": 1.0, - "loopFlag": false - }, - "children": [] - }, - { - "id": "landStand", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/jump_standing_land_settle.fbx", - "startFrame": 6.0, - "endFrame": 68.0, - "timeScale": 1.0, - "loopFlag": false - }, - "children": [] - }, - { - "id": "LANDRUN", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/jump_running_launch_land.fbx", - "startFrame": 29.0, - "endFrame": 40.0, - "timeScale": 1.0, - "loopFlag": false - }, - "children": [] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - }, - { - "id": "userAnimA", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/idle.fbx", - "startFrame": 0.0, - "endFrame": 90.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - }, - { - "id": "userAnimB", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/idle.fbx", - "startFrame": 0.0, - "endFrame": 90.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - } - ] - } -} diff --git a/interface/resources/avatar/avatar-animation_withIKNode.json b/interface/resources/avatar/avatar-animation_withSplineIKNode.json similarity index 100% rename from interface/resources/avatar/avatar-animation_withIKNode.json rename to interface/resources/avatar/avatar-animation_withSplineIKNode.json From 2679a3a30d554805914ae974907a359d03d53748 Mon Sep 17 00:00:00 2001 From: Angus Antley Date: Sun, 27 Jan 2019 16:30:13 -0800 Subject: [PATCH 023/112] changed the naming of the middle joint from secondary target to midJoint, also generalized the handling of the neck head rotation after the middle spline is updated --- .../avatar-animation_withSplineIKNode.json | 6 +- libraries/animation/src/AnimNodeLoader.cpp | 13 ++-- libraries/animation/src/AnimSplineIK.cpp | 77 ++++++++----------- libraries/animation/src/AnimSplineIK.h | 13 +--- 4 files changed, 46 insertions(+), 63 deletions(-) diff --git a/interface/resources/avatar/avatar-animation_withSplineIKNode.json b/interface/resources/avatar/avatar-animation_withSplineIKNode.json index bd0baf473e..40572f698b 100644 --- a/interface/resources/avatar/avatar-animation_withSplineIKNode.json +++ b/interface/resources/avatar/avatar-animation_withSplineIKNode.json @@ -182,14 +182,14 @@ "enabled": false, "interpDuration": 15, "baseJointName": "Hips", + "midJointName": "Spine2", "tipJointName": "Head", - "secondaryTargetJointName": "Spine2", "basePositionVar": "hipsPosition", "baseRotationVar": "hipsRotation", + "midPositionVar": "spine2Position", + "midRotationVar": "spine2Rotation", "tipPositionVar": "headPosition", "tipRotationVar": "headRotation", - "secondaryTargetPositionVar": "spine2Position", - "secondaryTargetRotationVar": "spine2Rotation", "alphaVar": "splineIKAlpha", "enabledVar": "splineIKEnabled", "endEffectorRotationVarVar": "splineIKRotationVar", diff --git a/libraries/animation/src/AnimNodeLoader.cpp b/libraries/animation/src/AnimNodeLoader.cpp index bce242b50d..8a19b763bb 100644 --- a/libraries/animation/src/AnimNodeLoader.cpp +++ b/libraries/animation/src/AnimNodeLoader.cpp @@ -584,14 +584,14 @@ static AnimNode::Pointer loadSplineIKNode(const QJsonObject& jsonObj, const QStr READ_BOOL(enabled, jsonObj, id, jsonUrl, nullptr); READ_FLOAT(interpDuration, jsonObj, id, jsonUrl, nullptr); READ_STRING(baseJointName, jsonObj, id, jsonUrl, nullptr); + READ_STRING(midJointName, jsonObj, id, jsonUrl, nullptr); READ_STRING(tipJointName, jsonObj, id, jsonUrl, nullptr); - READ_STRING(secondaryTargetJointName, jsonObj, id, jsonUrl, nullptr); READ_STRING(basePositionVar, jsonObj, id, jsonUrl, nullptr); READ_STRING(baseRotationVar, jsonObj, id, jsonUrl, nullptr); + READ_STRING(midPositionVar, jsonObj, id, jsonUrl, nullptr); + READ_STRING(midRotationVar, jsonObj, id, jsonUrl, nullptr); READ_STRING(tipPositionVar, jsonObj, id, jsonUrl, nullptr); READ_STRING(tipRotationVar, jsonObj, id, jsonUrl, nullptr); - READ_STRING(secondaryTargetPositionVar, jsonObj, id, jsonUrl, nullptr); - READ_STRING(secondaryTargetRotationVar, jsonObj, id, jsonUrl, nullptr); READ_STRING(alphaVar, jsonObj, id, jsonUrl, nullptr); READ_STRING(enabledVar, jsonObj, id, jsonUrl, nullptr); READ_STRING(endEffectorRotationVarVar, jsonObj, id, jsonUrl, nullptr); @@ -600,11 +600,10 @@ static AnimNode::Pointer loadSplineIKNode(const QJsonObject& jsonObj, const QStr READ_STRING(secondaryFlexCoefficients, jsonObj, id, jsonUrl, nullptr); auto node = std::make_shared(id, alpha, enabled, interpDuration, - baseJointName, tipJointName, + baseJointName, midJointName, tipJointName, alphaVar, enabledVar, endEffectorRotationVarVar, endEffectorPositionVarVar, - basePositionVar, baseRotationVar, - tipPositionVar, tipRotationVar, secondaryTargetJointName, secondaryTargetPositionVar, - secondaryTargetRotationVar, primaryFlexCoefficients, secondaryFlexCoefficients); + basePositionVar, baseRotationVar, midPositionVar, midRotationVar, + tipPositionVar, tipRotationVar, primaryFlexCoefficients, secondaryFlexCoefficients); return node; } diff --git a/libraries/animation/src/AnimSplineIK.cpp b/libraries/animation/src/AnimSplineIK.cpp index b38850773d..27e295ffb0 100644 --- a/libraries/animation/src/AnimSplineIK.cpp +++ b/libraries/animation/src/AnimSplineIK.cpp @@ -19,16 +19,16 @@ static const float FRAMES_PER_SECOND = 30.0f; AnimSplineIK::AnimSplineIK(const QString& id, float alpha, bool enabled, float interpDuration, const QString& baseJointName, + const QString& midJointName, const QString& tipJointName, const QString& alphaVar, const QString& enabledVar, const QString& endEffectorRotationVarVar, const QString& endEffectorPositionVarVar, const QString& basePositionVar, const QString& baseRotationVar, + const QString& midPositionVar, + const QString& midRotationVar, const QString& tipPositionVar, const QString& tipRotationVar, - const QString& secondaryTargetJointName, - const QString& secondaryTargetPositionVar, - const QString& secondaryTargetRotationVar, const QString& primaryFlexCoefficients, const QString& secondaryFlexCoefficients) : AnimNode(AnimNode::Type::SplineIK, id), @@ -36,6 +36,7 @@ AnimSplineIK::AnimSplineIK(const QString& id, float alpha, bool enabled, float i _enabled(enabled), _interpDuration(interpDuration), _baseJointName(baseJointName), + _midJointName(midJointName), _tipJointName(tipJointName), _alphaVar(alphaVar), _enabledVar(enabledVar), @@ -45,11 +46,10 @@ AnimSplineIK::AnimSplineIK(const QString& id, float alpha, bool enabled, float i _prevEndEffectorPositionVar(), _basePositionVar(basePositionVar), _baseRotationVar(baseRotationVar), + _midPositionVar(midPositionVar), + _midRotationVar(midRotationVar), _tipPositionVar(tipPositionVar), - _tipRotationVar(tipRotationVar), - _secondaryTargetJointName(secondaryTargetJointName), - _secondaryTargetPositionVar(secondaryTargetPositionVar), - _secondaryTargetRotationVar(secondaryTargetRotationVar) + _tipRotationVar(tipRotationVar) { QStringList flexCoefficientsValues = primaryFlexCoefficients.split(',', QString::SkipEmptyParts); @@ -182,17 +182,17 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const qCDebug(animation) << "the orig target pose for head " << target.getPose(); jointChain.outputRelativePoses(_poses); - AnimPose afterSolveSecondaryTarget = _skeleton->getAbsolutePose(_secondaryTargetIndex, _poses); - glm::quat secondaryTargetRotation = animVars.lookupRigToGeometry(_secondaryTargetRotationVar, afterSolveSecondaryTarget.rot()); + AnimPose afterSolveSecondaryTarget = _skeleton->getAbsolutePose(_midJointIndex, _poses); + glm::quat secondaryTargetRotation = animVars.lookupRigToGeometry(_midRotationVar, afterSolveSecondaryTarget.rot()); updatedSecondaryTarget = AnimPose(secondaryTargetRotation, afterSolveSecondaryTarget.trans()); //updatedSecondaryTarget = AnimPose(afterSolveSecondaryTarget.rot(), afterSolveSecondaryTarget.trans()); } IKTarget secondaryTarget; computeAbsolutePoses(absolutePoses2); - if (_secondaryTargetIndex != -1) { + if (_midJointIndex != -1) { secondaryTarget.setType((int)IKTarget::Type::Spline); - secondaryTarget.setIndex(_secondaryTargetIndex); + secondaryTarget.setIndex(_midJointIndex); float weight2 = 1.0f; secondaryTarget.setPose(updatedSecondaryTarget.rot(), updatedSecondaryTarget.trans()); @@ -204,8 +204,17 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const AnimChain secondaryJointChain; AnimPose beforeSolveChestNeck; + int startJoint; + AnimPose correctJoint; if (_poses.size() > 0) { + // start at the tip + + for (startJoint = _tipJointIndex; _skeleton->getParentIndex(startJoint) != _midJointIndex; startJoint = _skeleton->getParentIndex(startJoint)) { + // find the child of the midJoint + } + correctJoint = _skeleton->getAbsolutePose(startJoint, _poses); + // fix this to deal with no neck AA beforeSolveChestNeck = _skeleton->getAbsolutePose(_skeleton->nameToJointIndex("Neck"), _poses); @@ -216,16 +225,19 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const // set the tip/head rotation to match the absolute rotation of the target. int tipParent = _skeleton->getParentIndex(_tipJointIndex); - int secondaryTargetParent = _skeleton->getParentIndex(_secondaryTargetIndex); + int secondaryTargetParent = _skeleton->getParentIndex(_midJointIndex); if ((secondaryTargetParent != -1) && (tipParent != -1) && (_poses.size() > 0)) { - AnimPose secondaryTargetPose(secondaryTarget.getRotation(), secondaryTarget.getTranslation()); - AnimPose neckAbsolute = _skeleton->getAbsolutePose(tipParent, _poses); - _poses[tipParent] = secondaryTargetPose.inverse() * beforeSolveChestNeck; + - AnimPose tipTarget(target.getRotation(),target.getTranslation()); - AnimPose tipRelativePose = _skeleton->getAbsolutePose(tipParent,_poses).inverse() * tipTarget; - _poses[_tipJointIndex] = tipRelativePose; + AnimPose secondaryTargetPose(secondaryTarget.getRotation(), secondaryTarget.getTranslation()); + //AnimPose neckAbsolute = _skeleton->getAbsolutePose(tipParent, _poses); + //_poses[tipParent] = secondaryTargetPose.inverse() * beforeSolveChestNeck; + _poses[startJoint] = secondaryTargetPose.inverse() * correctJoint; + + //AnimPose tipTarget(target.getRotation(),target.getTranslation()); + //AnimPose tipRelativePose = _skeleton->getAbsolutePose(tipParent,_poses).inverse() * tipTarget; + //_poses[_tipJointIndex] = tipRelativePose; } // compute chain @@ -311,12 +323,12 @@ void AnimSplineIK::lookUpIndices() { assert(_skeleton); // look up bone indices by name - std::vector indices = _skeleton->lookUpJointIndices({ _baseJointName, _tipJointName, _secondaryTargetJointName }); + std::vector indices = _skeleton->lookUpJointIndices({ _baseJointName, _tipJointName, _midJointName }); // cache the results _baseJointIndex = indices[0]; _tipJointIndex = indices[1]; - _secondaryTargetIndex = indices[2]; + _midJointIndex = indices[2]; if (_baseJointIndex != -1) { _baseParentJointIndex = _skeleton->getParentIndex(_baseJointIndex); @@ -362,7 +374,7 @@ static CubicHermiteSplineFunctorWithArcLength computeSplineFromTipAndBase(const void AnimSplineIK::solveTargetWithSpline(const AnimContext& context, const IKTarget& target, const AnimPoseVec& absolutePoses, bool debug, AnimChain& chainInfoOut) const { const int baseIndex = _baseJointIndex; - const int tipBaseIndex = _secondaryTargetIndex; + const int tipBaseIndex = _midJointIndex; // build spline from tip to base AnimPose tipPose = AnimPose(glm::vec3(1.0f), target.getRotation(), target.getTranslation()); @@ -556,29 +568,6 @@ void AnimSplineIK::loadPoses(const AnimPoseVec& poses) { } } - -void AnimSplineIK::setTargetVars(const QString& jointName, const QString& positionVar, const QString& rotationVar, - const QString& typeVar, const QString& weightVar, float weight, const std::vector& flexCoefficients, - const QString& poleVectorEnabledVar, const QString& poleReferenceVectorVar, const QString& poleVectorVar) { - /* - IKTargetVar targetVar(jointName, positionVar, rotationVar, typeVar, weightVar, weight, flexCoefficients, poleVectorEnabledVar, poleReferenceVectorVar, poleVectorVar); - - // if there are dups, last one wins. - bool found = false; - for (auto& targetVarIter : _targetVarVec) { - if (targetVarIter.jointName == jointName) { - targetVarIter = targetVar; - found = true; - break; - } - } - if (!found) { - // create a new entry - _targetVarVec.push_back(targetVar); - } - */ -} - void AnimSplineIK::beginInterp(InterpType interpType, const AnimChain& chain) { // capture the current poses in a snapshot. _snapshotChain = chain; diff --git a/libraries/animation/src/AnimSplineIK.h b/libraries/animation/src/AnimSplineIK.h index c6d435fd6b..b05c5f4849 100644 --- a/libraries/animation/src/AnimSplineIK.h +++ b/libraries/animation/src/AnimSplineIK.h @@ -60,15 +60,13 @@ protected: float _interpDuration; QString _baseJointName; QString _tipJointName; - QString _secondaryTargetJointName; + QString _midJointName; QString _basePositionVar; QString _baseRotationVar; + QString _midPositionVar; + QString _midRotationVar; QString _tipPositionVar; QString _tipRotationVar; - QString _secondaryTargetPositionVar; - QString _secondaryTargetRotationVar; - //QString _primaryFlexCoefficients; - //QString _secondaryFlexCoefficients; static const int MAX_NUMBER_FLEX_VARIABLES = 10; float _primaryFlexCoefficients[MAX_NUMBER_FLEX_VARIABLES]; @@ -78,7 +76,7 @@ protected: int _baseParentJointIndex { -1 }; int _baseJointIndex { -1 }; - int _secondaryTargetIndex { -1 }; + int _midJointIndex { -1 }; int _tipJointIndex { -1 }; int _headIndex { -1 }; int _hipsIndex { -1 }; @@ -110,9 +108,6 @@ protected: bool _lastEnableDebugDrawIKTargets{ false }; void AnimSplineIK::solveTargetWithSpline(const AnimContext& context, const IKTarget& target, const AnimPoseVec& absolutePoses, bool debug, AnimChain& chainInfoOut) const; - void AnimSplineIK::setTargetVars(const QString& jointName, const QString& positionVar, const QString& rotationVar, - const QString& typeVar, const QString& weightVar, float weight, const std::vector& flexCoefficients, - const QString& poleVectorEnabledVar, const QString& poleReferenceVectorVar, const QString& poleVectorVar); void computeAndCacheSplineJointInfosForIKTarget(const AnimContext& context, const IKTarget& target) const; const std::vector* findOrCreateSplineJointInfo(const AnimContext& context, const IKTarget& target) const; mutable std::map> _splineJointInfoMap; From f8bfef6dbd6d96232bb97012fe50aff26038e1bb Mon Sep 17 00:00:00 2001 From: amantley Date: Mon, 28 Jan 2019 11:50:23 -0800 Subject: [PATCH 024/112] cleaning up the _hipsIndex references, cleaning in general --- .../avatar-animation_withSplineIKNode.json | 4 +- libraries/animation/src/AnimNodeLoader.cpp | 6 +- libraries/animation/src/AnimSplineIK.cpp | 157 +++++++++--------- libraries/animation/src/AnimSplineIK.h | 18 +- 4 files changed, 85 insertions(+), 100 deletions(-) diff --git a/interface/resources/avatar/avatar-animation_withSplineIKNode.json b/interface/resources/avatar/avatar-animation_withSplineIKNode.json index 40572f698b..aac1312e72 100644 --- a/interface/resources/avatar/avatar-animation_withSplineIKNode.json +++ b/interface/resources/avatar/avatar-animation_withSplineIKNode.json @@ -194,8 +194,8 @@ "enabledVar": "splineIKEnabled", "endEffectorRotationVarVar": "splineIKRotationVar", "endEffectorPositionVarVar": "splineIKPositionVar", - "primaryFlexCoefficients": "1.0, 1.0, 1.0, 1.0, 1.0", - "secondaryFlexCoefficients": "1.0, 1.0, 1.0" + "tipTargetFlexCoefficients": "1.0, 1.0, 1.0, 1.0, 1.0", + "midTargetFlexCoefficients": "1.0, 1.0, 1.0" }, "children": [ { diff --git a/libraries/animation/src/AnimNodeLoader.cpp b/libraries/animation/src/AnimNodeLoader.cpp index 8a19b763bb..47c8c7f0bb 100644 --- a/libraries/animation/src/AnimNodeLoader.cpp +++ b/libraries/animation/src/AnimNodeLoader.cpp @@ -596,14 +596,14 @@ static AnimNode::Pointer loadSplineIKNode(const QJsonObject& jsonObj, const QStr READ_STRING(enabledVar, jsonObj, id, jsonUrl, nullptr); READ_STRING(endEffectorRotationVarVar, jsonObj, id, jsonUrl, nullptr); READ_STRING(endEffectorPositionVarVar, jsonObj, id, jsonUrl, nullptr); - READ_STRING(primaryFlexCoefficients, jsonObj, id, jsonUrl, nullptr); - READ_STRING(secondaryFlexCoefficients, jsonObj, id, jsonUrl, nullptr); + READ_STRING(tipTargetFlexCoefficients, jsonObj, id, jsonUrl, nullptr); + READ_STRING(midTargetFlexCoefficients, jsonObj, id, jsonUrl, nullptr); auto node = std::make_shared(id, alpha, enabled, interpDuration, baseJointName, midJointName, tipJointName, alphaVar, enabledVar, endEffectorRotationVarVar, endEffectorPositionVarVar, basePositionVar, baseRotationVar, midPositionVar, midRotationVar, - tipPositionVar, tipRotationVar, primaryFlexCoefficients, secondaryFlexCoefficients); + tipPositionVar, tipRotationVar, tipTargetFlexCoefficients, midTargetFlexCoefficients); return node; } diff --git a/libraries/animation/src/AnimSplineIK.cpp b/libraries/animation/src/AnimSplineIK.cpp index 27e295ffb0..7c8f950537 100644 --- a/libraries/animation/src/AnimSplineIK.cpp +++ b/libraries/animation/src/AnimSplineIK.cpp @@ -29,8 +29,8 @@ AnimSplineIK::AnimSplineIK(const QString& id, float alpha, bool enabled, float i const QString& midRotationVar, const QString& tipPositionVar, const QString& tipRotationVar, - const QString& primaryFlexCoefficients, - const QString& secondaryFlexCoefficients) : + const QString& tipTargetFlexCoefficients, + const QString& midTargetFlexCoefficients) : AnimNode(AnimNode::Type::SplineIK, id), _alpha(alpha), _enabled(enabled), @@ -52,22 +52,22 @@ AnimSplineIK::AnimSplineIK(const QString& id, float alpha, bool enabled, float i _tipRotationVar(tipRotationVar) { - QStringList flexCoefficientsValues = primaryFlexCoefficients.split(',', QString::SkipEmptyParts); - for (int i = 0; i < flexCoefficientsValues.size(); i++) { + QStringList tipTargetFlexCoefficientsValues = tipTargetFlexCoefficients.split(',', QString::SkipEmptyParts); + for (int i = 0; i < tipTargetFlexCoefficientsValues.size(); i++) { if (i < MAX_NUMBER_FLEX_VARIABLES) { - qCDebug(animation) << "flex value " << flexCoefficientsValues[i].toDouble(); - _primaryFlexCoefficients[i] = (float)flexCoefficientsValues[i].toDouble(); + qCDebug(animation) << "tip target flex value " << tipTargetFlexCoefficientsValues[i].toDouble(); + _tipTargetFlexCoefficients[i] = (float)tipTargetFlexCoefficientsValues[i].toDouble(); } } - _numPrimaryFlexCoefficients = std::min(flexCoefficientsValues.size(), MAX_NUMBER_FLEX_VARIABLES); - QStringList secondaryFlexCoefficientsValues = secondaryFlexCoefficients.split(',', QString::SkipEmptyParts); - for (int i = 0; i < secondaryFlexCoefficientsValues.size(); i++) { + _numTipTargetFlexCoefficients = std::min(tipTargetFlexCoefficientsValues.size(), MAX_NUMBER_FLEX_VARIABLES); + QStringList midTargetFlexCoefficientsValues = midTargetFlexCoefficients.split(',', QString::SkipEmptyParts); + for (int i = 0; i < midTargetFlexCoefficientsValues.size(); i++) { if (i < MAX_NUMBER_FLEX_VARIABLES) { - qCDebug(animation) << "secondaryflex value " << secondaryFlexCoefficientsValues[i].toDouble(); - _secondaryFlexCoefficients[i] = (float)secondaryFlexCoefficientsValues[i].toDouble(); + qCDebug(animation) << "mid target flex value " << midTargetFlexCoefficientsValues[i].toDouble(); + _midTargetFlexCoefficients[i] = (float)midTargetFlexCoefficientsValues[i].toDouble(); } } - _numSecondaryFlexCoefficients = std::min(secondaryFlexCoefficientsValues.size(), MAX_NUMBER_FLEX_VARIABLES); + _numMidTargetFlexCoefficients = std::min(midTargetFlexCoefficientsValues.size(), MAX_NUMBER_FLEX_VARIABLES); } @@ -130,86 +130,79 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const AnimChain underChain; underChain.buildFromRelativePoses(_skeleton, underPoses, _tipJointIndex); - glm::quat hipsTargetRotation; - glm::vec3 hipsTargetTranslation; + glm::quat baseTargetRotation; + glm::vec3 baseTargetTranslation; // now we override the hips with the hips target pose. + // if there is a baseJoint ik target in animvars then use that + // otherwise use the underpose if (_poses.size() > 0) { - AnimPose hipsUnderPose = _skeleton->getAbsolutePose(_hipsIndex, _poses); - hipsTargetRotation = animVars.lookupRigToGeometry("hipsRotation", hipsUnderPose.rot()); - hipsTargetTranslation = animVars.lookupRigToGeometry("hipsPosition", hipsUnderPose.trans()); - AnimPose absHipsTargetPose(hipsTargetRotation, hipsTargetTranslation); + AnimPose baseJointUnderPose = _skeleton->getAbsolutePose(_baseJointIndex, _poses); + baseTargetRotation = animVars.lookupRigToGeometry(_baseRotationVar, baseJointUnderPose.rot()); + baseTargetTranslation = animVars.lookupRigToGeometry(_basePositionVar, baseJointUnderPose.trans()); + AnimPose absBaseTargetPose(baseTargetRotation, baseTargetTranslation); - int hipsParentIndex = _skeleton->getParentIndex(_hipsIndex); - AnimPose hipsParentAbsPose = _skeleton->getAbsolutePose(hipsParentIndex, _poses); + int baseParentIndex = _skeleton->getParentIndex(_baseJointIndex); + AnimPose baseParentAbsPose(Quaternions::IDENTITY,glm::vec3()); + if (baseParentIndex >= 0) { + baseParentAbsPose = _skeleton->getAbsolutePose(baseParentIndex, _poses); + } - _poses[_hipsIndex] = hipsParentAbsPose.inverse() * absHipsTargetPose; - _poses[_hipsIndex].scale() = glm::vec3(1.0f); + _poses[_baseJointIndex] = baseParentAbsPose.inverse() * absBaseTargetPose; + _poses[_baseJointIndex].scale() = glm::vec3(1.0f); } - AnimPoseVec absolutePoses; - absolutePoses.resize(_poses.size()); - computeAbsolutePoses(absolutePoses); - - IKTarget target; + IKTarget tipTarget; if (_tipJointIndex != -1) { - target.setType((int)IKTarget::Type::Spline); - target.setIndex(_tipJointIndex); + tipTarget.setType((int)IKTarget::Type::Spline); + tipTarget.setIndex(_tipJointIndex); + AnimPose absPose = _skeleton->getAbsolutePose(_tipJointIndex, _poses); glm::quat rotation = animVars.lookupRigToGeometry(_tipRotationVar, absPose.rot()); glm::vec3 translation = animVars.lookupRigToGeometry(_tipPositionVar, absPose.trans()); - float weight = 1.0f; - - target.setPose(rotation, translation); - target.setWeight(weight); - - - - const float* flexCoefficients = new float[5]{ 1.0f, 0.5f, 0.25f, 0.2f, 0.1f }; - target.setFlexCoefficients(_numPrimaryFlexCoefficients, _primaryFlexCoefficients); + tipTarget.setPose(rotation, translation); + tipTarget.setWeight(1.0f); + tipTarget.setFlexCoefficients(_numTipTargetFlexCoefficients, _tipTargetFlexCoefficients); } AnimChain jointChain; - AnimPose updatedSecondaryTarget; - AnimPoseVec absolutePoses2; - absolutePoses2.resize(_poses.size()); + if (_poses.size() > 0) { - jointChain.buildFromRelativePoses(_skeleton, _poses, target.getIndex()); - solveTargetWithSpline(context, target, absolutePoses, false, jointChain); + AnimPoseVec absolutePoses; + absolutePoses.resize(_poses.size()); + computeAbsolutePoses(absolutePoses); + jointChain.buildFromRelativePoses(_skeleton, _poses, tipTarget.getIndex()); + solveTargetWithSpline(context, tipTarget, absolutePoses, false, jointChain); jointChain.buildDirtyAbsolutePoses(); - qCDebug(animation) << "the jointChain Result for head " << jointChain.getAbsolutePoseFromJointIndex(_tipJointIndex); - qCDebug(animation) << "the orig target pose for head " << target.getPose(); jointChain.outputRelativePoses(_poses); - - AnimPose afterSolveSecondaryTarget = _skeleton->getAbsolutePose(_midJointIndex, _poses); - glm::quat secondaryTargetRotation = animVars.lookupRigToGeometry(_midRotationVar, afterSolveSecondaryTarget.rot()); - updatedSecondaryTarget = AnimPose(secondaryTargetRotation, afterSolveSecondaryTarget.trans()); - //updatedSecondaryTarget = AnimPose(afterSolveSecondaryTarget.rot(), afterSolveSecondaryTarget.trans()); } - IKTarget secondaryTarget; - computeAbsolutePoses(absolutePoses2); + IKTarget midTarget; if (_midJointIndex != -1) { - secondaryTarget.setType((int)IKTarget::Type::Spline); - secondaryTarget.setIndex(_midJointIndex); + midTarget.setType((int)IKTarget::Type::Spline); + midTarget.setIndex(_midJointIndex); - float weight2 = 1.0f; - secondaryTarget.setPose(updatedSecondaryTarget.rot(), updatedSecondaryTarget.trans()); - secondaryTarget.setWeight(weight2); - - const float* flexCoefficients2 = new float[3]{ 1.0f, 0.5f, 0.25f }; - secondaryTarget.setFlexCoefficients(_numSecondaryFlexCoefficients, _secondaryFlexCoefficients); + // set the middle joint to the position that is determined by the base-tip spline. + AnimPose afterSolveMidTarget = _skeleton->getAbsolutePose(_midJointIndex, _poses); + glm::quat midTargetRotation = animVars.lookupRigToGeometry(_midRotationVar, afterSolveMidTarget.rot()); + AnimPose updatedMidTarget = AnimPose(midTargetRotation, afterSolveMidTarget.trans()); + midTarget.setPose(updatedMidTarget.rot(), updatedMidTarget.trans()); + midTarget.setWeight(1.0f); + midTarget.setFlexCoefficients(_numMidTargetFlexCoefficients, _midTargetFlexCoefficients); } - AnimChain secondaryJointChain; + AnimChain midJointChain; AnimPose beforeSolveChestNeck; int startJoint; AnimPose correctJoint; if (_poses.size() > 0) { + AnimPoseVec absolutePoses2; + absolutePoses2.resize(_poses.size()); + computeAbsolutePoses(absolutePoses2); + // start at the tip - for (startJoint = _tipJointIndex; _skeleton->getParentIndex(startJoint) != _midJointIndex; startJoint = _skeleton->getParentIndex(startJoint)) { // find the child of the midJoint } @@ -218,25 +211,25 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const // fix this to deal with no neck AA beforeSolveChestNeck = _skeleton->getAbsolutePose(_skeleton->nameToJointIndex("Neck"), _poses); - secondaryJointChain.buildFromRelativePoses(_skeleton, _poses, secondaryTarget.getIndex()); - solveTargetWithSpline(context, secondaryTarget, absolutePoses2, false, secondaryJointChain); - secondaryJointChain.outputRelativePoses(_poses); + midJointChain.buildFromRelativePoses(_skeleton, _poses, midTarget.getIndex()); + solveTargetWithSpline(context, midTarget, absolutePoses2, false, midJointChain); + midJointChain.outputRelativePoses(_poses); } // set the tip/head rotation to match the absolute rotation of the target. int tipParent = _skeleton->getParentIndex(_tipJointIndex); - int secondaryTargetParent = _skeleton->getParentIndex(_midJointIndex); - if ((secondaryTargetParent != -1) && (tipParent != -1) && (_poses.size() > 0)) { + int midTargetParent = _skeleton->getParentIndex(_midJointIndex); + if ((midTargetParent != -1) && (tipParent != -1) && (_poses.size() > 0)) { - AnimPose secondaryTargetPose(secondaryTarget.getRotation(), secondaryTarget.getTranslation()); + AnimPose midTargetPose(midTarget.getRotation(), midTarget.getTranslation()); //AnimPose neckAbsolute = _skeleton->getAbsolutePose(tipParent, _poses); - //_poses[tipParent] = secondaryTargetPose.inverse() * beforeSolveChestNeck; - _poses[startJoint] = secondaryTargetPose.inverse() * correctJoint; + //_poses[tipParent] = midTargetPose.inverse() * beforeSolveChestNeck; + _poses[startJoint] = midTargetPose.inverse() * correctJoint; - //AnimPose tipTarget(target.getRotation(),target.getTranslation()); - //AnimPose tipRelativePose = _skeleton->getAbsolutePose(tipParent,_poses).inverse() * tipTarget; + //AnimPose tipTargetPose(tipTarget.getRotation(),tipTarget.getTranslation()); + //AnimPose tipRelativePose = _skeleton->getAbsolutePose(tipParent,_poses).inverse() * tipTargetPose; //_poses[_tipJointIndex] = tipRelativePose; } @@ -286,31 +279,31 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const const vec4 GREEN(0.0f, 1.0f, 0.0f, 1.0f); glm::mat4 rigToAvatarMat = createMatFromQuatAndPos(Quaternions::Y_180, glm::vec3()); - glm::mat4 geomTargetMat = createMatFromQuatAndPos(target.getRotation(), target.getTranslation()); + glm::mat4 geomTargetMat = createMatFromQuatAndPos(tipTarget.getRotation(), tipTarget.getTranslation()); glm::mat4 avatarTargetMat = rigToAvatarMat * context.getGeometryToRigMatrix() * geomTargetMat; - QString name = QString("ikTargetHead"); + QString name = QString("ikTargetSplineTip"); DebugDraw::getInstance().addMyAvatarMarker(name, glmExtractRotation(avatarTargetMat), extractTranslation(avatarTargetMat), WHITE); - glm::mat4 geomTargetMat2 = createMatFromQuatAndPos(secondaryTarget.getRotation(), secondaryTarget.getTranslation()); + glm::mat4 geomTargetMat2 = createMatFromQuatAndPos(midTarget.getRotation(), midTarget.getTranslation()); glm::mat4 avatarTargetMat2 = rigToAvatarMat * context.getGeometryToRigMatrix() * geomTargetMat2; - QString name2 = QString("ikTargetSpine2"); + QString name2 = QString("ikTargetSplineMid"); DebugDraw::getInstance().addMyAvatarMarker(name2, glmExtractRotation(avatarTargetMat2), extractTranslation(avatarTargetMat2), WHITE); - glm::mat4 geomTargetMat3 = createMatFromQuatAndPos(hipsTargetRotation, hipsTargetTranslation); + glm::mat4 geomTargetMat3 = createMatFromQuatAndPos(baseTargetRotation,baseTargetTranslation); glm::mat4 avatarTargetMat3 = rigToAvatarMat * context.getGeometryToRigMatrix() * geomTargetMat3; - QString name3 = QString("ikTargetHips"); + QString name3 = QString("ikTargetSplineBase"); DebugDraw::getInstance().addMyAvatarMarker(name3, glmExtractRotation(avatarTargetMat3), extractTranslation(avatarTargetMat3), WHITE); } else if (context.getEnableDebugDrawIKTargets() != _previousEnableDebugIKTargets) { // remove markers if they were added last frame. - QString name = QString("ikTargetHead"); + QString name = QString("ikTargetSplineTip"); DebugDraw::getInstance().removeMyAvatarMarker(name); - QString name2 = QString("ikTargetSpine2"); + QString name2 = QString("ikTargetSplineMid"); DebugDraw::getInstance().removeMyAvatarMarker(name2); - QString name3 = QString("ikTargetHips"); + QString name3 = QString("ikTargetSplineBase"); DebugDraw::getInstance().removeMyAvatarMarker(name3); } @@ -356,8 +349,6 @@ const AnimPoseVec& AnimSplineIK::getPosesInternal() const { void AnimSplineIK::setSkeletonInternal(AnimSkeleton::ConstPointer skeleton) { AnimNode::setSkeletonInternal(skeleton); - //_headIndex = _skeleton->nameToJointIndex("Head"); - _hipsIndex = _skeleton->nameToJointIndex("Hips"); lookUpIndices(); } diff --git a/libraries/animation/src/AnimSplineIK.h b/libraries/animation/src/AnimSplineIK.h index b05c5f4849..abc34618b3 100644 --- a/libraries/animation/src/AnimSplineIK.h +++ b/libraries/animation/src/AnimSplineIK.h @@ -19,14 +19,12 @@ class AnimSplineIK : public AnimNode { public: AnimSplineIK(const QString& id, float alpha, bool enabled, float interpDuration, - const QString& baseJointName, const QString& tipJointName, + const QString& baseJointName, const QString& midJointName, const QString& tipJointName, const QString& alphaVar, const QString& enabledVar, const QString& endEffectorRotationVarVar, const QString& endEffectorPositionVarVar, const QString& basePositionVar, const QString& baseRotationVar, + const QString& midPositionVar, const QString& midRotationVar, const QString& tipPositionVar, const QString& tipRotationVar, - const QString& secondaryTargetJointName, - const QString& secondaryTargetPositionVar, - const QString& secondaryTargetRotationVar, const QString& primaryFlexCoefficients, const QString& secondaryFlexCoefficients); @@ -69,19 +67,15 @@ protected: QString _tipRotationVar; static const int MAX_NUMBER_FLEX_VARIABLES = 10; - float _primaryFlexCoefficients[MAX_NUMBER_FLEX_VARIABLES]; - float _secondaryFlexCoefficients[MAX_NUMBER_FLEX_VARIABLES]; - int _numPrimaryFlexCoefficients { 0 }; - int _numSecondaryFlexCoefficients { 0 }; + float _tipTargetFlexCoefficients[MAX_NUMBER_FLEX_VARIABLES]; + float _midTargetFlexCoefficients[MAX_NUMBER_FLEX_VARIABLES]; + int _numTipTargetFlexCoefficients { 0 }; + int _numMidTargetFlexCoefficients { 0 }; int _baseParentJointIndex { -1 }; int _baseJointIndex { -1 }; int _midJointIndex { -1 }; int _tipJointIndex { -1 }; - int _headIndex { -1 }; - int _hipsIndex { -1 }; - int _spine2Index { -1 }; - int _hipsTargetIndex { -1 }; QString _alphaVar; // float - (0, 1) 0 means underPoses only, 1 means IK only. QString _enabledVar; // bool From ffd3a24bf22c7f4e6cd2f4604693e7d83da40422 Mon Sep 17 00:00:00 2001 From: amantley Date: Mon, 28 Jan 2019 13:53:30 -0800 Subject: [PATCH 025/112] further cleaning, broke the arms --- .../avatar-animation_withSplineIKNode.json | 2 - libraries/animation/src/AnimNodeLoader.cpp | 6 +- libraries/animation/src/AnimSplineIK.cpp | 78 ++++++------------- libraries/animation/src/AnimSplineIK.h | 12 +-- 4 files changed, 29 insertions(+), 69 deletions(-) diff --git a/interface/resources/avatar/avatar-animation_withSplineIKNode.json b/interface/resources/avatar/avatar-animation_withSplineIKNode.json index aac1312e72..a6283f0771 100644 --- a/interface/resources/avatar/avatar-animation_withSplineIKNode.json +++ b/interface/resources/avatar/avatar-animation_withSplineIKNode.json @@ -192,8 +192,6 @@ "tipRotationVar": "headRotation", "alphaVar": "splineIKAlpha", "enabledVar": "splineIKEnabled", - "endEffectorRotationVarVar": "splineIKRotationVar", - "endEffectorPositionVarVar": "splineIKPositionVar", "tipTargetFlexCoefficients": "1.0, 1.0, 1.0, 1.0, 1.0", "midTargetFlexCoefficients": "1.0, 1.0, 1.0" }, diff --git a/libraries/animation/src/AnimNodeLoader.cpp b/libraries/animation/src/AnimNodeLoader.cpp index 47c8c7f0bb..62e848872b 100644 --- a/libraries/animation/src/AnimNodeLoader.cpp +++ b/libraries/animation/src/AnimNodeLoader.cpp @@ -594,16 +594,14 @@ static AnimNode::Pointer loadSplineIKNode(const QJsonObject& jsonObj, const QStr READ_STRING(tipRotationVar, jsonObj, id, jsonUrl, nullptr); READ_STRING(alphaVar, jsonObj, id, jsonUrl, nullptr); READ_STRING(enabledVar, jsonObj, id, jsonUrl, nullptr); - READ_STRING(endEffectorRotationVarVar, jsonObj, id, jsonUrl, nullptr); - READ_STRING(endEffectorPositionVarVar, jsonObj, id, jsonUrl, nullptr); READ_STRING(tipTargetFlexCoefficients, jsonObj, id, jsonUrl, nullptr); READ_STRING(midTargetFlexCoefficients, jsonObj, id, jsonUrl, nullptr); auto node = std::make_shared(id, alpha, enabled, interpDuration, baseJointName, midJointName, tipJointName, - alphaVar, enabledVar, endEffectorRotationVarVar, endEffectorPositionVarVar, basePositionVar, baseRotationVar, midPositionVar, midRotationVar, - tipPositionVar, tipRotationVar, tipTargetFlexCoefficients, midTargetFlexCoefficients); + tipPositionVar, tipRotationVar, alphaVar, enabledVar, + tipTargetFlexCoefficients, midTargetFlexCoefficients); return node; } diff --git a/libraries/animation/src/AnimSplineIK.cpp b/libraries/animation/src/AnimSplineIK.cpp index 7c8f950537..5355a02b3e 100644 --- a/libraries/animation/src/AnimSplineIK.cpp +++ b/libraries/animation/src/AnimSplineIK.cpp @@ -21,14 +21,14 @@ AnimSplineIK::AnimSplineIK(const QString& id, float alpha, bool enabled, float i const QString& baseJointName, const QString& midJointName, const QString& tipJointName, - const QString& alphaVar, const QString& enabledVar, - const QString& endEffectorRotationVarVar, const QString& endEffectorPositionVarVar, const QString& basePositionVar, const QString& baseRotationVar, const QString& midPositionVar, const QString& midRotationVar, const QString& tipPositionVar, const QString& tipRotationVar, + const QString& alphaVar, + const QString& enabledVar, const QString& tipTargetFlexCoefficients, const QString& midTargetFlexCoefficients) : AnimNode(AnimNode::Type::SplineIK, id), @@ -38,18 +38,14 @@ AnimSplineIK::AnimSplineIK(const QString& id, float alpha, bool enabled, float i _baseJointName(baseJointName), _midJointName(midJointName), _tipJointName(tipJointName), - _alphaVar(alphaVar), - _enabledVar(enabledVar), - _endEffectorRotationVarVar(endEffectorRotationVarVar), - _endEffectorPositionVarVar(endEffectorPositionVarVar), - _prevEndEffectorRotationVar(), - _prevEndEffectorPositionVar(), _basePositionVar(basePositionVar), _baseRotationVar(baseRotationVar), _midPositionVar(midPositionVar), _midRotationVar(midRotationVar), _tipPositionVar(tipPositionVar), - _tipRotationVar(tipRotationVar) + _tipRotationVar(tipRotationVar), + _alphaVar(alphaVar), + _enabledVar(enabledVar) { QStringList tipTargetFlexCoefficientsValues = tipTargetFlexCoefficients.split(',', QString::SkipEmptyParts); @@ -101,7 +97,7 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const return _poses; } - // guard against size changes + // guard against size change if (underPoses.size() != _poses.size()) { _poses = underPoses; } @@ -130,17 +126,14 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const AnimChain underChain; underChain.buildFromRelativePoses(_skeleton, underPoses, _tipJointIndex); - glm::quat baseTargetRotation; - glm::vec3 baseTargetTranslation; - + AnimPose baseTargetAbsolutePose; // now we override the hips with the hips target pose. // if there is a baseJoint ik target in animvars then use that // otherwise use the underpose if (_poses.size() > 0) { AnimPose baseJointUnderPose = _skeleton->getAbsolutePose(_baseJointIndex, _poses); - baseTargetRotation = animVars.lookupRigToGeometry(_baseRotationVar, baseJointUnderPose.rot()); - baseTargetTranslation = animVars.lookupRigToGeometry(_basePositionVar, baseJointUnderPose.trans()); - AnimPose absBaseTargetPose(baseTargetRotation, baseTargetTranslation); + baseTargetAbsolutePose.rot() = animVars.lookupRigToGeometry(_baseRotationVar, baseJointUnderPose.rot()); + baseTargetAbsolutePose.trans() = animVars.lookupRigToGeometry(_basePositionVar, baseJointUnderPose.trans()); int baseParentIndex = _skeleton->getParentIndex(_baseJointIndex); AnimPose baseParentAbsPose(Quaternions::IDENTITY,glm::vec3()); @@ -148,7 +141,7 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const baseParentAbsPose = _skeleton->getAbsolutePose(baseParentIndex, _poses); } - _poses[_baseJointIndex] = baseParentAbsPose.inverse() * absBaseTargetPose; + _poses[_baseJointIndex] = baseParentAbsPose.inverse() * baseTargetAbsolutePose; _poses[_baseJointIndex].scale() = glm::vec3(1.0f); } @@ -193,26 +186,22 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const } AnimChain midJointChain; - AnimPose beforeSolveChestNeck; - int startJoint; - AnimPose correctJoint; + int childOfMiddleJointIndex = -1; + AnimPose childOfMiddleJointAbsolutePoseAfterBaseTipSpline; if (_poses.size() > 0) { - AnimPoseVec absolutePoses2; - absolutePoses2.resize(_poses.size()); - computeAbsolutePoses(absolutePoses2); - + childOfMiddleJointIndex = _tipJointIndex; // start at the tip - for (startJoint = _tipJointIndex; _skeleton->getParentIndex(startJoint) != _midJointIndex; startJoint = _skeleton->getParentIndex(startJoint)) { - // find the child of the midJoint + while (_skeleton->getParentIndex(childOfMiddleJointIndex) != _midJointIndex) { + childOfMiddleJointIndex = _skeleton->getParentIndex(childOfMiddleJointIndex); } - correctJoint = _skeleton->getAbsolutePose(startJoint, _poses); - - // fix this to deal with no neck AA - beforeSolveChestNeck = _skeleton->getAbsolutePose(_skeleton->nameToJointIndex("Neck"), _poses); + childOfMiddleJointAbsolutePoseAfterBaseTipSpline = _skeleton->getAbsolutePose(childOfMiddleJointIndex, _poses); + AnimPoseVec absolutePosesAfterBaseTipSpline; + absolutePosesAfterBaseTipSpline.resize(_poses.size()); + computeAbsolutePoses(absolutePosesAfterBaseTipSpline); midJointChain.buildFromRelativePoses(_skeleton, _poses, midTarget.getIndex()); - solveTargetWithSpline(context, midTarget, absolutePoses2, false, midJointChain); + solveTargetWithSpline(context, midTarget, absolutePosesAfterBaseTipSpline, false, midJointChain); midJointChain.outputRelativePoses(_poses); } @@ -220,17 +209,8 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const int tipParent = _skeleton->getParentIndex(_tipJointIndex); int midTargetParent = _skeleton->getParentIndex(_midJointIndex); if ((midTargetParent != -1) && (tipParent != -1) && (_poses.size() > 0)) { - - - AnimPose midTargetPose(midTarget.getRotation(), midTarget.getTranslation()); - //AnimPose neckAbsolute = _skeleton->getAbsolutePose(tipParent, _poses); - //_poses[tipParent] = midTargetPose.inverse() * beforeSolveChestNeck; - _poses[startJoint] = midTargetPose.inverse() * correctJoint; - - //AnimPose tipTargetPose(tipTarget.getRotation(),tipTarget.getTranslation()); - //AnimPose tipRelativePose = _skeleton->getAbsolutePose(tipParent,_poses).inverse() * tipTargetPose; - //_poses[_tipJointIndex] = tipRelativePose; + _poses[childOfMiddleJointIndex] = midTargetPose.inverse() * childOfMiddleJointAbsolutePoseAfterBaseTipSpline; } // compute chain @@ -290,7 +270,7 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const DebugDraw::getInstance().addMyAvatarMarker(name2, glmExtractRotation(avatarTargetMat2), extractTranslation(avatarTargetMat2), WHITE); - glm::mat4 geomTargetMat3 = createMatFromQuatAndPos(baseTargetRotation,baseTargetTranslation); + glm::mat4 geomTargetMat3 = createMatFromQuatAndPos(baseTargetAbsolutePose.rot(), baseTargetAbsolutePose.trans()); glm::mat4 avatarTargetMat3 = rigToAvatarMat * context.getGeometryToRigMatrix() * geomTargetMat3; QString name3 = QString("ikTargetSplineBase"); DebugDraw::getInstance().addMyAvatarMarker(name3, glmExtractRotation(avatarTargetMat3), extractTranslation(avatarTargetMat3), WHITE); @@ -369,12 +349,7 @@ void AnimSplineIK::solveTargetWithSpline(const AnimContext& context, const IKTar // build spline from tip to base AnimPose tipPose = AnimPose(glm::vec3(1.0f), target.getRotation(), target.getTranslation()); - AnimPose basePose; - //if (target.getIndex() == _tipJointIndex) { - // basePose = absolutePoses[tipBaseIndex]; - //} else { - basePose = absolutePoses[baseIndex]; - //} + AnimPose basePose = absolutePoses[baseIndex]; CubicHermiteSplineFunctorWithArcLength spline; if (target.getIndex() == _tipJointIndex) { @@ -382,7 +357,6 @@ void AnimSplineIK::solveTargetWithSpline(const AnimContext& context, const IKTar const float HIPS_GAIN = 0.5f; const float HEAD_GAIN = 1.0f; spline = computeSplineFromTipAndBase(tipPose, basePose, HIPS_GAIN, HEAD_GAIN); - // spline = computeSplineFromTipAndBase(tipPose, basePose); } else { spline = computeSplineFromTipAndBase(tipPose, basePose); } @@ -406,7 +380,7 @@ void AnimSplineIK::solveTargetWithSpline(const AnimContext& context, const IKTar float t = spline.arcLengthInverse(splineJointInfo.ratio * totalArcLength); glm::vec3 trans = spline(t); - // for head splines, preform most twist toward the tip by using ease in function. t^2 + // for base->tip splines, preform most twist toward the tip by using ease in function. t^2 float rotT = t; if (target.getIndex() == _tipJointIndex) { rotT = t * t; @@ -454,9 +428,6 @@ void AnimSplineIK::solveTargetWithSpline(const AnimContext& context, const IKTar if (!chainInfoOut.setRelativePoseAtJointIndex(splineJointInfo.jointIndex, relPose)) { qCDebug(animation) << "we didn't find the joint index for the spline!!!!"; } - if (splineJointInfo.jointIndex == _skeleton->nameToJointIndex("Neck")) { - qCDebug(animation) << "neck is " << relPose; - } parentAbsPose = flexedAbsPose; } @@ -518,7 +489,6 @@ void AnimSplineIK::computeAndCacheSplineJointInfosForIKTarget(const AnimContext& int index = target.getIndex(); int endIndex; if (target.getIndex() == _tipJointIndex) { - //endIndex = _skeleton->getParentIndex(_secondaryTargetIndex); endIndex = _skeleton->getParentIndex(_baseJointIndex); } else { endIndex = _skeleton->getParentIndex(_baseJointIndex); diff --git a/libraries/animation/src/AnimSplineIK.h b/libraries/animation/src/AnimSplineIK.h index abc34618b3..ea7a897362 100644 --- a/libraries/animation/src/AnimSplineIK.h +++ b/libraries/animation/src/AnimSplineIK.h @@ -20,13 +20,12 @@ class AnimSplineIK : public AnimNode { public: AnimSplineIK(const QString& id, float alpha, bool enabled, float interpDuration, const QString& baseJointName, const QString& midJointName, const QString& tipJointName, - const QString& alphaVar, const QString& enabledVar, - const QString& endEffectorRotationVarVar, const QString& endEffectorPositionVarVar, const QString& basePositionVar, const QString& baseRotationVar, const QString& midPositionVar, const QString& midRotationVar, const QString& tipPositionVar, const QString& tipRotationVar, - const QString& primaryFlexCoefficients, - const QString& secondaryFlexCoefficients); + const QString& alphaVar, const QString& enabledVar, + const QString& tipTargetFlexCoefficients, + const QString& midTargetFlexCoefficients); virtual ~AnimSplineIK() override; virtual const AnimPoseVec& evaluate(const AnimVariantMap& animVars, const AnimContext& context, float dt, AnimVariantMap& triggersOut) override; @@ -79,11 +78,6 @@ protected: QString _alphaVar; // float - (0, 1) 0 means underPoses only, 1 means IK only. QString _enabledVar; // bool - QString _endEffectorRotationVarVar; // string - QString _endEffectorPositionVarVar; // string - - QString _prevEndEffectorRotationVar; - QString _prevEndEffectorPositionVar; bool _previousEnableDebugIKTargets { false }; From f17cfbcbb188eb68bbdca695f50879d90a88a324 Mon Sep 17 00:00:00 2001 From: amantley Date: Mon, 28 Jan 2019 15:25:12 -0800 Subject: [PATCH 026/112] more cleaning, need to fix debug draw ik chain --- libraries/animation/src/AnimSplineIK.cpp | 141 ++++++++++------------- libraries/animation/src/AnimSplineIK.h | 4 +- 2 files changed, 60 insertions(+), 85 deletions(-) diff --git a/libraries/animation/src/AnimSplineIK.cpp b/libraries/animation/src/AnimSplineIK.cpp index 5355a02b3e..af1f3e9524 100644 --- a/libraries/animation/src/AnimSplineIK.cpp +++ b/libraries/animation/src/AnimSplineIK.cpp @@ -90,8 +90,8 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const // evaluate underPoses AnimPoseVec underPoses = _children[0]->evaluate(animVars, context, dt, triggersOut); - // if we don't have a skeleton, or jointName lookup failed. - if (!_skeleton || _baseJointIndex == -1 || _tipJointIndex == -1 || alpha == 0.0f || underPoses.size() == 0) { + // if we don't have a skeleton, or jointName lookup failed or the spline alpha is 0 or there are no underposes. + if (!_skeleton || _baseJointIndex == -1 || _midJointIndex == -1 || _tipJointIndex == -1 || alpha == 0.0f || underPoses.size() == 0) { // pass underPoses through unmodified. _poses = underPoses; return _poses; @@ -115,6 +115,7 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const } _enabled = enabled; + // now that we have saved the previous _poses in _snapshotChain, we can update to the current underposes _poses = underPoses; // don't build chains or do IK if we are disabled & not interping. @@ -127,91 +128,75 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const underChain.buildFromRelativePoses(_skeleton, underPoses, _tipJointIndex); AnimPose baseTargetAbsolutePose; - // now we override the hips with the hips target pose. - // if there is a baseJoint ik target in animvars then use that + // if there is a baseJoint ik target in animvars then set the joint to that // otherwise use the underpose - if (_poses.size() > 0) { - AnimPose baseJointUnderPose = _skeleton->getAbsolutePose(_baseJointIndex, _poses); - baseTargetAbsolutePose.rot() = animVars.lookupRigToGeometry(_baseRotationVar, baseJointUnderPose.rot()); - baseTargetAbsolutePose.trans() = animVars.lookupRigToGeometry(_basePositionVar, baseJointUnderPose.trans()); + AnimPose baseJointUnderPose = _skeleton->getAbsolutePose(_baseJointIndex, _poses); + baseTargetAbsolutePose.rot() = animVars.lookupRigToGeometry(_baseRotationVar, baseJointUnderPose.rot()); + baseTargetAbsolutePose.trans() = animVars.lookupRigToGeometry(_basePositionVar, baseJointUnderPose.trans()); - int baseParentIndex = _skeleton->getParentIndex(_baseJointIndex); - AnimPose baseParentAbsPose(Quaternions::IDENTITY,glm::vec3()); - if (baseParentIndex >= 0) { - baseParentAbsPose = _skeleton->getAbsolutePose(baseParentIndex, _poses); - } - - _poses[_baseJointIndex] = baseParentAbsPose.inverse() * baseTargetAbsolutePose; - _poses[_baseJointIndex].scale() = glm::vec3(1.0f); + int baseParentIndex = _skeleton->getParentIndex(_baseJointIndex); + AnimPose baseParentAbsPose(Quaternions::IDENTITY,glm::vec3()); + if (baseParentIndex >= 0) { + baseParentAbsPose = _skeleton->getAbsolutePose(baseParentIndex, _poses); } + _poses[_baseJointIndex] = baseParentAbsPose.inverse() * baseTargetAbsolutePose; + _poses[_baseJointIndex].scale() = glm::vec3(1.0f); + // initialize the tip target IKTarget tipTarget; - if (_tipJointIndex != -1) { - tipTarget.setType((int)IKTarget::Type::Spline); - tipTarget.setIndex(_tipJointIndex); - - AnimPose absPose = _skeleton->getAbsolutePose(_tipJointIndex, _poses); - glm::quat rotation = animVars.lookupRigToGeometry(_tipRotationVar, absPose.rot()); - glm::vec3 translation = animVars.lookupRigToGeometry(_tipPositionVar, absPose.trans()); - tipTarget.setPose(rotation, translation); - tipTarget.setWeight(1.0f); - tipTarget.setFlexCoefficients(_numTipTargetFlexCoefficients, _tipTargetFlexCoefficients); - } + tipTarget.setType((int)IKTarget::Type::Spline); + tipTarget.setIndex(_tipJointIndex); + AnimPose absPose = _skeleton->getAbsolutePose(_tipJointIndex, _poses); + glm::quat rotation = animVars.lookupRigToGeometry(_tipRotationVar, absPose.rot()); + glm::vec3 translation = animVars.lookupRigToGeometry(_tipPositionVar, absPose.trans()); + tipTarget.setPose(rotation, translation); + tipTarget.setWeight(1.0f); + tipTarget.setFlexCoefficients(_numTipTargetFlexCoefficients, _tipTargetFlexCoefficients); + AnimChain jointChain; - - if (_poses.size() > 0) { - - AnimPoseVec absolutePoses; - absolutePoses.resize(_poses.size()); - computeAbsolutePoses(absolutePoses); - jointChain.buildFromRelativePoses(_skeleton, _poses, tipTarget.getIndex()); - solveTargetWithSpline(context, tipTarget, absolutePoses, false, jointChain); - jointChain.buildDirtyAbsolutePoses(); - jointChain.outputRelativePoses(_poses); - } + AnimPoseVec absolutePoses; + absolutePoses.resize(_poses.size()); + computeAbsolutePoses(absolutePoses); + jointChain.buildFromRelativePoses(_skeleton, _poses, tipTarget.getIndex()); + solveTargetWithSpline(context, tipTarget, absolutePoses, false, jointChain); + jointChain.buildDirtyAbsolutePoses(); + jointChain.outputRelativePoses(_poses); + // initialize the middle joint target IKTarget midTarget; - if (_midJointIndex != -1) { - midTarget.setType((int)IKTarget::Type::Spline); - midTarget.setIndex(_midJointIndex); - - // set the middle joint to the position that is determined by the base-tip spline. - AnimPose afterSolveMidTarget = _skeleton->getAbsolutePose(_midJointIndex, _poses); - glm::quat midTargetRotation = animVars.lookupRigToGeometry(_midRotationVar, afterSolveMidTarget.rot()); - AnimPose updatedMidTarget = AnimPose(midTargetRotation, afterSolveMidTarget.trans()); - midTarget.setPose(updatedMidTarget.rot(), updatedMidTarget.trans()); - midTarget.setWeight(1.0f); - midTarget.setFlexCoefficients(_numMidTargetFlexCoefficients, _midTargetFlexCoefficients); - } + midTarget.setType((int)IKTarget::Type::Spline); + midTarget.setIndex(_midJointIndex); + // set the middle joint to the position that was just determined by the base-tip spline. + AnimPose afterSolveMidTarget = _skeleton->getAbsolutePose(_midJointIndex, _poses); + // use the rotation from the ik target value, if there is one. + glm::quat midTargetRotation = animVars.lookupRigToGeometry(_midRotationVar, afterSolveMidTarget.rot()); + AnimPose updatedMidTarget = AnimPose(midTargetRotation, afterSolveMidTarget.trans()); + midTarget.setPose(updatedMidTarget.rot(), updatedMidTarget.trans()); + midTarget.setWeight(1.0f); + midTarget.setFlexCoefficients(_numMidTargetFlexCoefficients, _midTargetFlexCoefficients); AnimChain midJointChain; + // Find the pose of the middle target's child. This is to correct the mid to tip + // after the base to mid spline is set. int childOfMiddleJointIndex = -1; AnimPose childOfMiddleJointAbsolutePoseAfterBaseTipSpline; - if (_poses.size() > 0) { - - childOfMiddleJointIndex = _tipJointIndex; - // start at the tip - while (_skeleton->getParentIndex(childOfMiddleJointIndex) != _midJointIndex) { - childOfMiddleJointIndex = _skeleton->getParentIndex(childOfMiddleJointIndex); - } - childOfMiddleJointAbsolutePoseAfterBaseTipSpline = _skeleton->getAbsolutePose(childOfMiddleJointIndex, _poses); - - AnimPoseVec absolutePosesAfterBaseTipSpline; - absolutePosesAfterBaseTipSpline.resize(_poses.size()); - computeAbsolutePoses(absolutePosesAfterBaseTipSpline); - midJointChain.buildFromRelativePoses(_skeleton, _poses, midTarget.getIndex()); - solveTargetWithSpline(context, midTarget, absolutePosesAfterBaseTipSpline, false, midJointChain); - midJointChain.outputRelativePoses(_poses); + childOfMiddleJointIndex = _tipJointIndex; + while (_skeleton->getParentIndex(childOfMiddleJointIndex) != _midJointIndex) { + childOfMiddleJointIndex = _skeleton->getParentIndex(childOfMiddleJointIndex); } + childOfMiddleJointAbsolutePoseAfterBaseTipSpline = _skeleton->getAbsolutePose(childOfMiddleJointIndex, _poses); - // set the tip/head rotation to match the absolute rotation of the target. - int tipParent = _skeleton->getParentIndex(_tipJointIndex); - int midTargetParent = _skeleton->getParentIndex(_midJointIndex); - if ((midTargetParent != -1) && (tipParent != -1) && (_poses.size() > 0)) { - AnimPose midTargetPose(midTarget.getRotation(), midTarget.getTranslation()); - _poses[childOfMiddleJointIndex] = midTargetPose.inverse() * childOfMiddleJointAbsolutePoseAfterBaseTipSpline; - } + AnimPoseVec absolutePosesAfterBaseTipSpline; + absolutePosesAfterBaseTipSpline.resize(_poses.size()); + computeAbsolutePoses(absolutePosesAfterBaseTipSpline); + midJointChain.buildFromRelativePoses(_skeleton, _poses, midTarget.getIndex()); + solveTargetWithSpline(context, midTarget, absolutePosesAfterBaseTipSpline, false, midJointChain); + midJointChain.outputRelativePoses(_poses); + + // set the mid to tip segment to match the absolute rotation of the target. + AnimPose midTargetPose(midTarget.getRotation(), midTarget.getTranslation()); + _poses[childOfMiddleJointIndex] = midTargetPose.inverse() * childOfMiddleJointAbsolutePoseAfterBaseTipSpline; // compute chain AnimChain ikChain; @@ -424,7 +409,6 @@ void AnimSplineIK::solveTargetWithSpline(const AnimContext& context, const IKTar relPose.trans() = glm::vec3(0.0f); } } - // note we are ignoring the constrained info for now. if (!chainInfoOut.setRelativePoseAtJointIndex(splineJointInfo.jointIndex, relPose)) { qCDebug(animation) << "we didn't find the joint index for the spline!!!!"; } @@ -450,7 +434,6 @@ const std::vector* AnimSplineIK::findOrCreateSpli return &(iter->second); } } - return nullptr; } @@ -460,13 +443,7 @@ void AnimSplineIK::computeAndCacheSplineJointInfosForIKTarget(const AnimContext& // build spline between the default poses. AnimPose tipPose = _skeleton->getAbsoluteDefaultPose(target.getIndex()); - AnimPose basePose; - if (target.getIndex() == _tipJointIndex) { - basePose = _skeleton->getAbsoluteDefaultPose(_baseJointIndex); - //basePose = _skeleton->getAbsoluteDefaultPose(_secondaryTargetIndex); - } else { - basePose = _skeleton->getAbsoluteDefaultPose(_baseJointIndex); - } + AnimPose basePose = _skeleton->getAbsoluteDefaultPose(_baseJointIndex); CubicHermiteSplineFunctorWithArcLength spline; if (target.getIndex() == _tipJointIndex) { @@ -474,7 +451,6 @@ void AnimSplineIK::computeAndCacheSplineJointInfosForIKTarget(const AnimContext& const float HIPS_GAIN = 0.5f; const float HEAD_GAIN = 1.0f; spline = computeSplineFromTipAndBase(tipPose, basePose, HIPS_GAIN, HEAD_GAIN); - // spline = computeSplineFromTipAndBase(tipPose, basePose); } else { spline = computeSplineFromTipAndBase(tipPose, basePose); } @@ -516,7 +492,6 @@ void AnimSplineIK::computeAndCacheSplineJointInfosForIKTarget(const AnimContext& splineJointInfoVec.push_back(splineJointInfo); index = _skeleton->getParentIndex(index); } - _splineJointInfoMap[target.getIndex()] = splineJointInfoVec; } diff --git a/libraries/animation/src/AnimSplineIK.h b/libraries/animation/src/AnimSplineIK.h index ea7a897362..2109d43456 100644 --- a/libraries/animation/src/AnimSplineIK.h +++ b/libraries/animation/src/AnimSplineIK.h @@ -87,14 +87,14 @@ protected: AnimChain _snapshotChain; - // used to pre-compute information about each joint influeced by a spline IK target. + // used to pre-compute information about each joint influenced by a spline IK target. struct SplineJointInfo { int jointIndex; // joint in the skeleton that this information pertains to. float ratio; // percentage (0..1) along the spline for this joint. AnimPose offsetPose; // local offset from the spline to the joint. }; - bool _lastEnableDebugDrawIKTargets{ false }; + bool _lastEnableDebugDrawIKTargets { false }; void AnimSplineIK::solveTargetWithSpline(const AnimContext& context, const IKTarget& target, const AnimPoseVec& absolutePoses, bool debug, AnimChain& chainInfoOut) const; void computeAndCacheSplineJointInfosForIKTarget(const AnimContext& context, const IKTarget& target) const; const std::vector* findOrCreateSplineJointInfo(const AnimContext& context, const IKTarget& target) const; From dffd41ecb0d1b1d3cac0a7ae081f2cf62d232a43 Mon Sep 17 00:00:00 2001 From: amantley Date: Mon, 28 Jan 2019 16:58:28 -0800 Subject: [PATCH 027/112] chain ik debug draw works for spline now --- libraries/animation/src/AnimSplineIK.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/libraries/animation/src/AnimSplineIK.cpp b/libraries/animation/src/AnimSplineIK.cpp index af1f3e9524..39686dd3a2 100644 --- a/libraries/animation/src/AnimSplineIK.cpp +++ b/libraries/animation/src/AnimSplineIK.cpp @@ -91,7 +91,7 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const AnimPoseVec underPoses = _children[0]->evaluate(animVars, context, dt, triggersOut); // if we don't have a skeleton, or jointName lookup failed or the spline alpha is 0 or there are no underposes. - if (!_skeleton || _baseJointIndex == -1 || _midJointIndex == -1 || _tipJointIndex == -1 || alpha == 0.0f || underPoses.size() == 0) { + if (!_skeleton || _baseJointIndex == -1 || _tipJointIndex == -1 || alpha == 0.0f || underPoses.size() == 0) { // pass underPoses through unmodified. _poses = underPoses; return _poses; @@ -159,7 +159,7 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const absolutePoses.resize(_poses.size()); computeAbsolutePoses(absolutePoses); jointChain.buildFromRelativePoses(_skeleton, _poses, tipTarget.getIndex()); - solveTargetWithSpline(context, tipTarget, absolutePoses, false, jointChain); + solveTargetWithSpline(context, tipTarget, absolutePoses, context.getEnableDebugDrawIKChains(), jointChain); jointChain.buildDirtyAbsolutePoses(); jointChain.outputRelativePoses(_poses); @@ -191,7 +191,7 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const absolutePosesAfterBaseTipSpline.resize(_poses.size()); computeAbsolutePoses(absolutePosesAfterBaseTipSpline); midJointChain.buildFromRelativePoses(_skeleton, _poses, midTarget.getIndex()); - solveTargetWithSpline(context, midTarget, absolutePosesAfterBaseTipSpline, false, midJointChain); + solveTargetWithSpline(context, midTarget, absolutePosesAfterBaseTipSpline, context.getEnableDebugDrawIKChains(), midJointChain); midJointChain.outputRelativePoses(_poses); // set the mid to tip segment to match the absolute rotation of the target. @@ -418,7 +418,8 @@ void AnimSplineIK::solveTargetWithSpline(const AnimContext& context, const IKTar } if (debug) { - //debugDrawIKChain(jointChainInfoOut, context); + const vec4 CYAN(0.0f, 1.0f, 1.0f, 1.0f); + chainInfoOut.debugDraw(context.getRigToWorldMatrix() * context.getGeometryToRigMatrix(), CYAN); } } From 1919cc3b1aa5d8ab40cb1bbeb084034a577926b0 Mon Sep 17 00:00:00 2001 From: amantley Date: Mon, 28 Jan 2019 17:49:46 -0800 Subject: [PATCH 028/112] disable mid joint when not valid. more work on this tomorrow --- .../avatar-animation_withSplineIKNode.json | 2 +- libraries/animation/src/AnimSplineIK.cpp | 85 +++++++++++-------- 2 files changed, 49 insertions(+), 38 deletions(-) diff --git a/interface/resources/avatar/avatar-animation_withSplineIKNode.json b/interface/resources/avatar/avatar-animation_withSplineIKNode.json index a6283f0771..ce98368a87 100644 --- a/interface/resources/avatar/avatar-animation_withSplineIKNode.json +++ b/interface/resources/avatar/avatar-animation_withSplineIKNode.json @@ -182,7 +182,7 @@ "enabled": false, "interpDuration": 15, "baseJointName": "Hips", - "midJointName": "Spine2", + "midJointName": "none", "tipJointName": "Head", "basePositionVar": "hipsPosition", "baseRotationVar": "hipsRotation", diff --git a/libraries/animation/src/AnimSplineIK.cpp b/libraries/animation/src/AnimSplineIK.cpp index 39686dd3a2..cd2a0a19ee 100644 --- a/libraries/animation/src/AnimSplineIK.cpp +++ b/libraries/animation/src/AnimSplineIK.cpp @@ -163,40 +163,48 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const jointChain.buildDirtyAbsolutePoses(); jointChain.outputRelativePoses(_poses); - // initialize the middle joint target IKTarget midTarget; - midTarget.setType((int)IKTarget::Type::Spline); - midTarget.setIndex(_midJointIndex); - // set the middle joint to the position that was just determined by the base-tip spline. - AnimPose afterSolveMidTarget = _skeleton->getAbsolutePose(_midJointIndex, _poses); - // use the rotation from the ik target value, if there is one. - glm::quat midTargetRotation = animVars.lookupRigToGeometry(_midRotationVar, afterSolveMidTarget.rot()); - AnimPose updatedMidTarget = AnimPose(midTargetRotation, afterSolveMidTarget.trans()); - midTarget.setPose(updatedMidTarget.rot(), updatedMidTarget.trans()); - midTarget.setWeight(1.0f); - midTarget.setFlexCoefficients(_numMidTargetFlexCoefficients, _midTargetFlexCoefficients); + if (_midJointIndex != -1) { - AnimChain midJointChain; - // Find the pose of the middle target's child. This is to correct the mid to tip - // after the base to mid spline is set. - int childOfMiddleJointIndex = -1; - AnimPose childOfMiddleJointAbsolutePoseAfterBaseTipSpline; - childOfMiddleJointIndex = _tipJointIndex; - while (_skeleton->getParentIndex(childOfMiddleJointIndex) != _midJointIndex) { - childOfMiddleJointIndex = _skeleton->getParentIndex(childOfMiddleJointIndex); + // initialize the middle joint target + midTarget.setType((int)IKTarget::Type::Spline); + midTarget.setIndex(_midJointIndex); + // set the middle joint to the position that was just determined by the base-tip spline. + AnimPose afterSolveMidTarget = _skeleton->getAbsolutePose(_midJointIndex, _poses); + // use the rotation from the ik target value, if there is one. + glm::quat midTargetRotation = animVars.lookupRigToGeometry(_midRotationVar, afterSolveMidTarget.rot()); + AnimPose updatedMidTarget = AnimPose(midTargetRotation, afterSolveMidTarget.trans()); + midTarget.setPose(updatedMidTarget.rot(), updatedMidTarget.trans()); + midTarget.setWeight(1.0f); + midTarget.setFlexCoefficients(_numMidTargetFlexCoefficients, _midTargetFlexCoefficients); + + AnimChain midJointChain; + // Find the pose of the middle target's child. This is to correct the mid to tip + // after the base to mid spline is set. + int childOfMiddleJointIndex = -1; + AnimPose childOfMiddleJointAbsolutePoseAfterBaseTipSpline; + childOfMiddleJointIndex = _tipJointIndex; + while ((_skeleton->getParentIndex(childOfMiddleJointIndex) != _midJointIndex) && (childOfMiddleJointIndex != -1)) { + childOfMiddleJointIndex = _skeleton->getParentIndex(childOfMiddleJointIndex); + } + // if the middle joint is not actually between the base and the tip then don't create spline for it + if (childOfMiddleJointIndex != -1) { + childOfMiddleJointAbsolutePoseAfterBaseTipSpline = _skeleton->getAbsolutePose(childOfMiddleJointIndex, _poses); + + AnimPoseVec absolutePosesAfterBaseTipSpline; + absolutePosesAfterBaseTipSpline.resize(_poses.size()); + computeAbsolutePoses(absolutePosesAfterBaseTipSpline); + midJointChain.buildFromRelativePoses(_skeleton, _poses, midTarget.getIndex()); + solveTargetWithSpline(context, midTarget, absolutePosesAfterBaseTipSpline, context.getEnableDebugDrawIKChains(), midJointChain); + midJointChain.outputRelativePoses(_poses); + + // set the mid to tip segment to match the absolute rotation of the tip target. + AnimPose midTargetPose(midTarget.getRotation(), midTarget.getTranslation()); + _poses[childOfMiddleJointIndex] = midTargetPose.inverse() * childOfMiddleJointAbsolutePoseAfterBaseTipSpline; + } } - childOfMiddleJointAbsolutePoseAfterBaseTipSpline = _skeleton->getAbsolutePose(childOfMiddleJointIndex, _poses); - AnimPoseVec absolutePosesAfterBaseTipSpline; - absolutePosesAfterBaseTipSpline.resize(_poses.size()); - computeAbsolutePoses(absolutePosesAfterBaseTipSpline); - midJointChain.buildFromRelativePoses(_skeleton, _poses, midTarget.getIndex()); - solveTargetWithSpline(context, midTarget, absolutePosesAfterBaseTipSpline, context.getEnableDebugDrawIKChains(), midJointChain); - midJointChain.outputRelativePoses(_poses); - - // set the mid to tip segment to match the absolute rotation of the target. - AnimPose midTargetPose(midTarget.getRotation(), midTarget.getTranslation()); - _poses[childOfMiddleJointIndex] = midTargetPose.inverse() * childOfMiddleJointAbsolutePoseAfterBaseTipSpline; + // compute chain AnimChain ikChain; @@ -249,11 +257,12 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const QString name = QString("ikTargetSplineTip"); DebugDraw::getInstance().addMyAvatarMarker(name, glmExtractRotation(avatarTargetMat), extractTranslation(avatarTargetMat), WHITE); - glm::mat4 geomTargetMat2 = createMatFromQuatAndPos(midTarget.getRotation(), midTarget.getTranslation()); - glm::mat4 avatarTargetMat2 = rigToAvatarMat * context.getGeometryToRigMatrix() * geomTargetMat2; - QString name2 = QString("ikTargetSplineMid"); - DebugDraw::getInstance().addMyAvatarMarker(name2, glmExtractRotation(avatarTargetMat2), extractTranslation(avatarTargetMat2), WHITE); - + if (_midJointIndex != -1) { + glm::mat4 geomTargetMat2 = createMatFromQuatAndPos(midTarget.getRotation(), midTarget.getTranslation()); + glm::mat4 avatarTargetMat2 = rigToAvatarMat * context.getGeometryToRigMatrix() * geomTargetMat2; + QString name2 = QString("ikTargetSplineMid"); + DebugDraw::getInstance().addMyAvatarMarker(name2, glmExtractRotation(avatarTargetMat2), extractTranslation(avatarTargetMat2), WHITE); + } glm::mat4 geomTargetMat3 = createMatFromQuatAndPos(baseTargetAbsolutePose.rot(), baseTargetAbsolutePose.trans()); glm::mat4 avatarTargetMat3 = rigToAvatarMat * context.getGeometryToRigMatrix() * geomTargetMat3; @@ -266,8 +275,10 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const QString name = QString("ikTargetSplineTip"); DebugDraw::getInstance().removeMyAvatarMarker(name); - QString name2 = QString("ikTargetSplineMid"); - DebugDraw::getInstance().removeMyAvatarMarker(name2); + if (_midJointIndex != -1) { + QString name2 = QString("ikTargetSplineMid"); + DebugDraw::getInstance().removeMyAvatarMarker(name2); + } QString name3 = QString("ikTargetSplineBase"); DebugDraw::getInstance().removeMyAvatarMarker(name3); From 39943115832c8838cb49cbce096aa4ec5e131417 Mon Sep 17 00:00:00 2001 From: Angus Antley Date: Tue, 29 Jan 2019 08:54:35 -0800 Subject: [PATCH 029/112] starting the move of the initial head base spline to myskeletonmodel --- .../avatar-animation_withSplineIKNode.json | 2 +- libraries/animation/src/AnimSplineIK.cpp | 27 +++++++++++-------- libraries/animation/src/AnimSplineIK.h | 3 +-- 3 files changed, 18 insertions(+), 14 deletions(-) diff --git a/interface/resources/avatar/avatar-animation_withSplineIKNode.json b/interface/resources/avatar/avatar-animation_withSplineIKNode.json index ce98368a87..a6283f0771 100644 --- a/interface/resources/avatar/avatar-animation_withSplineIKNode.json +++ b/interface/resources/avatar/avatar-animation_withSplineIKNode.json @@ -182,7 +182,7 @@ "enabled": false, "interpDuration": 15, "baseJointName": "Hips", - "midJointName": "none", + "midJointName": "Spine2", "tipJointName": "Head", "basePositionVar": "hipsPosition", "baseRotationVar": "hipsRotation", diff --git a/libraries/animation/src/AnimSplineIK.cpp b/libraries/animation/src/AnimSplineIK.cpp index cd2a0a19ee..220546f31e 100644 --- a/libraries/animation/src/AnimSplineIK.cpp +++ b/libraries/animation/src/AnimSplineIK.cpp @@ -71,12 +71,6 @@ AnimSplineIK::~AnimSplineIK() { } -//virtual -const AnimPoseVec& AnimSplineIK::overlay(const AnimVariantMap& animVars, const AnimContext& context, float dt, AnimVariantMap& triggersOut, const AnimPoseVec& underPoses) { - loadPoses(underPoses); - return _poses; -} - const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const AnimContext& context, float dt, AnimVariantMap& triggersOut) { assert(_children.size() == 1); if (_children.size() != 1) { @@ -159,7 +153,7 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const absolutePoses.resize(_poses.size()); computeAbsolutePoses(absolutePoses); jointChain.buildFromRelativePoses(_skeleton, _poses, tipTarget.getIndex()); - solveTargetWithSpline(context, tipTarget, absolutePoses, context.getEnableDebugDrawIKChains(), jointChain); + solveTargetWithSpline(context, _baseJointIndex, tipTarget, absolutePoses, context.getEnableDebugDrawIKChains(), jointChain); jointChain.buildDirtyAbsolutePoses(); jointChain.outputRelativePoses(_poses); @@ -195,15 +189,27 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const absolutePosesAfterBaseTipSpline.resize(_poses.size()); computeAbsolutePoses(absolutePosesAfterBaseTipSpline); midJointChain.buildFromRelativePoses(_skeleton, _poses, midTarget.getIndex()); - solveTargetWithSpline(context, midTarget, absolutePosesAfterBaseTipSpline, context.getEnableDebugDrawIKChains(), midJointChain); + solveTargetWithSpline(context, _baseJointIndex, midTarget, absolutePosesAfterBaseTipSpline, context.getEnableDebugDrawIKChains(), midJointChain); midJointChain.outputRelativePoses(_poses); // set the mid to tip segment to match the absolute rotation of the tip target. AnimPose midTargetPose(midTarget.getRotation(), midTarget.getTranslation()); _poses[childOfMiddleJointIndex] = midTargetPose.inverse() * childOfMiddleJointAbsolutePoseAfterBaseTipSpline; } + + + AnimChain upperJointChain; + AnimPoseVec finalAbsolutePoses; + finalAbsolutePoses.resize(_poses.size()); + computeAbsolutePoses(finalAbsolutePoses); + upperJointChain.buildFromRelativePoses(_skeleton, _poses, tipTarget.getIndex()); + solveTargetWithSpline(context, _midJointIndex, tipTarget, finalAbsolutePoses, context.getEnableDebugDrawIKChains(), upperJointChain); + upperJointChain.buildDirtyAbsolutePoses(); + upperJointChain.outputRelativePoses(_poses); + } + // compute chain @@ -338,10 +344,9 @@ static CubicHermiteSplineFunctorWithArcLength computeSplineFromTipAndBase(const return CubicHermiteSplineFunctorWithArcLength(p0, m0, p1, m1); } -void AnimSplineIK::solveTargetWithSpline(const AnimContext& context, const IKTarget& target, const AnimPoseVec& absolutePoses, bool debug, AnimChain& chainInfoOut) const { +void AnimSplineIK::solveTargetWithSpline(const AnimContext& context, int base, const IKTarget& target, const AnimPoseVec& absolutePoses, bool debug, AnimChain& chainInfoOut) const { - const int baseIndex = _baseJointIndex; - const int tipBaseIndex = _midJointIndex; + const int baseIndex = base; // build spline from tip to base AnimPose tipPose = AnimPose(glm::vec3(1.0f), target.getRotation(), target.getTranslation()); diff --git a/libraries/animation/src/AnimSplineIK.h b/libraries/animation/src/AnimSplineIK.h index 2109d43456..5d45d9528f 100644 --- a/libraries/animation/src/AnimSplineIK.h +++ b/libraries/animation/src/AnimSplineIK.h @@ -29,7 +29,6 @@ public: virtual ~AnimSplineIK() override; virtual const AnimPoseVec& evaluate(const AnimVariantMap& animVars, const AnimContext& context, float dt, AnimVariantMap& triggersOut) override; - virtual const AnimPoseVec& overlay(const AnimVariantMap& animVars, const AnimContext& context, float dt, AnimVariantMap& triggersOut, const AnimPoseVec& underPoses) override; protected: @@ -95,7 +94,7 @@ protected: }; bool _lastEnableDebugDrawIKTargets { false }; - void AnimSplineIK::solveTargetWithSpline(const AnimContext& context, const IKTarget& target, const AnimPoseVec& absolutePoses, bool debug, AnimChain& chainInfoOut) const; + void AnimSplineIK::solveTargetWithSpline(const AnimContext& context, int base, const IKTarget& target, const AnimPoseVec& absolutePoses, bool debug, AnimChain& chainInfoOut) const; void computeAndCacheSplineJointInfosForIKTarget(const AnimContext& context, const IKTarget& target) const; const std::vector* findOrCreateSplineJointInfo(const AnimContext& context, const IKTarget& target) const; mutable std::map> _splineJointInfoMap; From e2a729b68b2edbd32d1e4e17cfab8e09101508c7 Mon Sep 17 00:00:00 2001 From: amantley Date: Tue, 29 Jan 2019 17:25:25 -0800 Subject: [PATCH 030/112] got the spline working in myskeleton model, need to clean up --- interface/src/avatar/MySkeletonModel.cpp | 44 ++++++++++++++++++++++++ interface/src/avatar/MySkeletonModel.h | 1 + libraries/animation/src/AnimSplineIK.cpp | 36 ++++++++++++------- libraries/animation/src/AnimSplineIK.h | 4 +-- 4 files changed, 70 insertions(+), 15 deletions(-) diff --git a/interface/src/avatar/MySkeletonModel.cpp b/interface/src/avatar/MySkeletonModel.cpp index 26d69841d0..352e7ce6b0 100755 --- a/interface/src/avatar/MySkeletonModel.cpp +++ b/interface/src/avatar/MySkeletonModel.cpp @@ -33,6 +33,39 @@ Rig::CharacterControllerState convertCharacterControllerState(CharacterControlle }; } +static CubicHermiteSplineFunctorWithArcLength computeSplineFromTipAndBase(const AnimPose& tipPose, const AnimPose& basePose, float baseGain = 1.0f, float tipGain = 1.0f) { + float linearDistance = glm::length(basePose.trans() - tipPose.trans()); + glm::vec3 p0 = basePose.trans(); + glm::vec3 m0 = baseGain * linearDistance * (basePose.rot() * Vectors::UNIT_Y); + glm::vec3 p1 = tipPose.trans(); + glm::vec3 m1 = tipGain * linearDistance * (tipPose.rot() * Vectors::UNIT_Y); + + return CubicHermiteSplineFunctorWithArcLength(p0, m0, p1, m1); +} + +static glm::vec3 computeSpine2WithHeadHipsSpline(MyAvatar* myAvatar, AnimPose hipsIKTargetPose, AnimPose headIKTargetPose) { + glm::vec3 basePosition = myAvatar->getAbsoluteDefaultJointTranslationInObjectFrame(myAvatar->getJointIndex("Hips")); + glm::vec3 tipPosition = myAvatar->getAbsoluteDefaultJointTranslationInObjectFrame(myAvatar->getJointIndex("Head")); + glm::vec3 spine2Position = myAvatar->getAbsoluteDefaultJointTranslationInObjectFrame(myAvatar->getJointIndex("Spine2")); + glm::vec3 baseToTip = tipPosition - basePosition; + float baseToTipLength = glm::length(baseToTip); + glm::vec3 baseToTipNormal = baseToTip / baseToTipLength; + glm::vec3 baseToSpine2 = spine2Position - basePosition; + float ratio = glm::dot(baseToSpine2, baseToTipNormal) / baseToTipLength; + + // the the ik targets to compute the spline with + CubicHermiteSplineFunctorWithArcLength spline = computeSplineFromTipAndBase(headIKTargetPose, hipsIKTargetPose); + + // measure the total arc length along the spline + float totalArcLength = spline.arcLength(1.0f); + float t = spline.arcLengthInverse(ratio * totalArcLength); + + glm::vec3 spine2Translation = spline(t); + + return spine2Translation; + +} + static AnimPose computeHipsInSensorFrame(MyAvatar* myAvatar, bool isFlying) { glm::mat4 worldToSensorMat = glm::inverse(myAvatar->getSensorToWorldMatrix()); @@ -233,6 +266,12 @@ void MySkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) { myAvatar->getControllerPoseInAvatarFrame(controller::Action::LEFT_HAND).isValid() && !(params.primaryControllerFlags[Rig::PrimaryControllerType_Spine2] & (uint8_t)Rig::ControllerFlags::Enabled)) { + controller::Pose headSplineControllerPose = myAvatar->getControllerPoseInSensorFrame(controller::Action::HEAD); + AnimPose headSplinePose(headSplineControllerPose.getRotation(), headSplineControllerPose.getTranslation()); + glm::vec3 spine2TargetTranslation = computeSpine2WithHeadHipsSpline(myAvatar, sensorHips, headSplinePose); + AnimPose sensorSpine2(Quaternions::IDENTITY, spine2TargetTranslation); + AnimPose rigSpine2 = sensorToRigPose * sensorSpine2; + const float SPINE2_ROTATION_FILTER = 0.5f; AnimPose currentSpine2Pose; AnimPose currentHeadPose; @@ -253,6 +292,11 @@ void MySkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) { } generateBasisVectors(up, fwd, u, v, w); AnimPose newSpinePose(glm::mat4(glm::vec4(w, 0.0f), glm::vec4(u, 0.0f), glm::vec4(v, 0.0f), glm::vec4(glm::vec3(0.0f, 0.0f, 0.0f), 1.0f))); + currentSpine2Pose.trans() = rigSpine2.trans(); + qCDebug(animation) << "my skeleton model spline spine2 " << rigSpine2.trans(); + qCDebug(animation) << "my skeleton model current spine2 " << currentSpine2Pose.trans(); + // qCDebug(animation) << "my skeleton model spline hips " << sensorToRigPose * sensorHips; + // qCDebug(animation) << "my skeleton model current hips " << currentHipsPose.trans(); currentSpine2Pose.rot() = safeLerp(currentSpine2Pose.rot(), newSpinePose.rot(), SPINE2_ROTATION_FILTER); params.primaryControllerPoses[Rig::PrimaryControllerType_Spine2] = currentSpine2Pose; params.primaryControllerFlags[Rig::PrimaryControllerType_Spine2] = (uint8_t)Rig::ControllerFlags::Enabled | (uint8_t)Rig::ControllerFlags::Estimated; diff --git a/interface/src/avatar/MySkeletonModel.h b/interface/src/avatar/MySkeletonModel.h index 9a3559ddf7..7ea142b011 100644 --- a/interface/src/avatar/MySkeletonModel.h +++ b/interface/src/avatar/MySkeletonModel.h @@ -12,6 +12,7 @@ #include #include #include "MyAvatar.h" +#include /// A skeleton loaded from a model. class MySkeletonModel : public SkeletonModel { diff --git a/libraries/animation/src/AnimSplineIK.cpp b/libraries/animation/src/AnimSplineIK.cpp index 220546f31e..3aca678fa3 100644 --- a/libraries/animation/src/AnimSplineIK.cpp +++ b/libraries/animation/src/AnimSplineIK.cpp @@ -147,7 +147,7 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const tipTarget.setWeight(1.0f); tipTarget.setFlexCoefficients(_numTipTargetFlexCoefficients, _tipTargetFlexCoefficients); - + /* AnimChain jointChain; AnimPoseVec absolutePoses; absolutePoses.resize(_poses.size()); @@ -156,6 +156,7 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const solveTargetWithSpline(context, _baseJointIndex, tipTarget, absolutePoses, context.getEnableDebugDrawIKChains(), jointChain); jointChain.buildDirtyAbsolutePoses(); jointChain.outputRelativePoses(_poses); + */ IKTarget midTarget; if (_midJointIndex != -1) { @@ -167,7 +168,9 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const AnimPose afterSolveMidTarget = _skeleton->getAbsolutePose(_midJointIndex, _poses); // use the rotation from the ik target value, if there is one. glm::quat midTargetRotation = animVars.lookupRigToGeometry(_midRotationVar, afterSolveMidTarget.rot()); - AnimPose updatedMidTarget = AnimPose(midTargetRotation, afterSolveMidTarget.trans()); + glm::vec3 midTargetPosition = animVars.lookupRigToGeometry(_midPositionVar, afterSolveMidTarget.trans()); + AnimPose updatedMidTarget = AnimPose(midTargetRotation, midTargetPosition); + //qCDebug(animation) << "spine2 in AnimSpline " << updatedMidTarget.trans(); midTarget.setPose(updatedMidTarget.rot(), updatedMidTarget.trans()); midTarget.setWeight(1.0f); midTarget.setFlexCoefficients(_numMidTargetFlexCoefficients, _midTargetFlexCoefficients); @@ -194,9 +197,10 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const // set the mid to tip segment to match the absolute rotation of the tip target. AnimPose midTargetPose(midTarget.getRotation(), midTarget.getTranslation()); - _poses[childOfMiddleJointIndex] = midTargetPose.inverse() * childOfMiddleJointAbsolutePoseAfterBaseTipSpline; + //_poses[childOfMiddleJointIndex] = midTargetPose.inverse() * childOfMiddleJointAbsolutePoseAfterBaseTipSpline; } + _splineJointInfoMap.clear(); AnimChain upperJointChain; AnimPoseVec finalAbsolutePoses; @@ -206,7 +210,7 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const solveTargetWithSpline(context, _midJointIndex, tipTarget, finalAbsolutePoses, context.getEnableDebugDrawIKChains(), upperJointChain); upperJointChain.buildDirtyAbsolutePoses(); upperJointChain.outputRelativePoses(_poses); - + } @@ -370,8 +374,10 @@ void AnimSplineIK::solveTargetWithSpline(const AnimContext& context, int base, c tipPose.rot() = -tipPose.rot(); } // find or create splineJointInfo for this target - const std::vector* splineJointInfoVec = findOrCreateSplineJointInfo(context, target); + const std::vector* splineJointInfoVec = findOrCreateSplineJointInfo(context, base, target); + //qCDebug(animation) << "the size of the splineJointInfo is " << splineJointInfoVec->size() << " and the base index is "<size() > 0) { const int baseParentIndex = _skeleton->getParentIndex(baseIndex); AnimPose parentAbsPose = (baseParentIndex >= 0) ? absolutePoses[baseParentIndex] : AnimPose(); @@ -403,9 +409,9 @@ void AnimSplineIK::solveTargetWithSpline(const AnimContext& context, int base, c ::blend(1, &absolutePoses[splineJointInfo.jointIndex], &desiredAbsPose, target.getFlexCoefficient(i), &flexedAbsPose); AnimPose relPose = parentAbsPose.inverse() * flexedAbsPose; - + /* bool constrained = false; - if (splineJointInfo.jointIndex != _baseJointIndex) { + if (splineJointInfo.jointIndex != base) { // constrain the amount the spine can stretch or compress float length = glm::length(relPose.trans()); const float EPSILON = 0.0001f; @@ -425,6 +431,7 @@ void AnimSplineIK::solveTargetWithSpline(const AnimContext& context, int base, c relPose.trans() = glm::vec3(0.0f); } } + */ if (!chainInfoOut.setRelativePoseAtJointIndex(splineJointInfo.jointIndex, relPose)) { qCDebug(animation) << "we didn't find the joint index for the spline!!!!"; } @@ -439,13 +446,13 @@ void AnimSplineIK::solveTargetWithSpline(const AnimContext& context, int base, c } } -const std::vector* AnimSplineIK::findOrCreateSplineJointInfo(const AnimContext& context, const IKTarget& target) const { +const std::vector* AnimSplineIK::findOrCreateSplineJointInfo(const AnimContext& context, int base, const IKTarget& target) const { // find or create splineJointInfo for this target auto iter = _splineJointInfoMap.find(target.getIndex()); if (iter != _splineJointInfoMap.end()) { return &(iter->second); } else { - computeAndCacheSplineJointInfosForIKTarget(context, target); + computeAndCacheSplineJointInfosForIKTarget(context, base, target); auto iter = _splineJointInfoMap.find(target.getIndex()); if (iter != _splineJointInfoMap.end()) { return &(iter->second); @@ -455,12 +462,14 @@ const std::vector* AnimSplineIK::findOrCreateSpli } // pre-compute information about each joint influenced by this spline IK target. -void AnimSplineIK::computeAndCacheSplineJointInfosForIKTarget(const AnimContext& context, const IKTarget& target) const { +void AnimSplineIK::computeAndCacheSplineJointInfosForIKTarget(const AnimContext& context, int base, const IKTarget& target) const { std::vector splineJointInfoVec; + //qCDebug(animation) << "the base in compute cache is " << base; + // build spline between the default poses. AnimPose tipPose = _skeleton->getAbsoluteDefaultPose(target.getIndex()); - AnimPose basePose = _skeleton->getAbsoluteDefaultPose(_baseJointIndex); + AnimPose basePose = _skeleton->getAbsoluteDefaultPose(base); CubicHermiteSplineFunctorWithArcLength spline; if (target.getIndex() == _tipJointIndex) { @@ -481,10 +490,11 @@ void AnimSplineIK::computeAndCacheSplineJointInfosForIKTarget(const AnimContext& int index = target.getIndex(); int endIndex; + // fix this statement. AA if (target.getIndex() == _tipJointIndex) { - endIndex = _skeleton->getParentIndex(_baseJointIndex); + endIndex = _skeleton->getParentIndex(base); } else { - endIndex = _skeleton->getParentIndex(_baseJointIndex); + endIndex = _skeleton->getParentIndex(base); } while (index != endIndex) { AnimPose defaultPose = _skeleton->getAbsoluteDefaultPose(index); diff --git a/libraries/animation/src/AnimSplineIK.h b/libraries/animation/src/AnimSplineIK.h index 5d45d9528f..d664cf37a4 100644 --- a/libraries/animation/src/AnimSplineIK.h +++ b/libraries/animation/src/AnimSplineIK.h @@ -95,8 +95,8 @@ protected: bool _lastEnableDebugDrawIKTargets { false }; void AnimSplineIK::solveTargetWithSpline(const AnimContext& context, int base, const IKTarget& target, const AnimPoseVec& absolutePoses, bool debug, AnimChain& chainInfoOut) const; - void computeAndCacheSplineJointInfosForIKTarget(const AnimContext& context, const IKTarget& target) const; - const std::vector* findOrCreateSplineJointInfo(const AnimContext& context, const IKTarget& target) const; + void computeAndCacheSplineJointInfosForIKTarget(const AnimContext& context, int base, const IKTarget& target) const; + const std::vector* findOrCreateSplineJointInfo(const AnimContext& context, int base, const IKTarget& target) const; mutable std::map> _splineJointInfoMap; // no copies From fb0ad7768c9cfc5c82a68c1f16f243afede8ff15 Mon Sep 17 00:00:00 2001 From: amantley Date: Tue, 29 Jan 2019 17:31:20 -0800 Subject: [PATCH 031/112] removed clear map --- interface/src/avatar/MySkeletonModel.cpp | 4 ---- libraries/animation/src/AnimSplineIK.cpp | 2 -- 2 files changed, 6 deletions(-) diff --git a/interface/src/avatar/MySkeletonModel.cpp b/interface/src/avatar/MySkeletonModel.cpp index 352e7ce6b0..38f18d2ac9 100755 --- a/interface/src/avatar/MySkeletonModel.cpp +++ b/interface/src/avatar/MySkeletonModel.cpp @@ -293,10 +293,6 @@ void MySkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) { generateBasisVectors(up, fwd, u, v, w); AnimPose newSpinePose(glm::mat4(glm::vec4(w, 0.0f), glm::vec4(u, 0.0f), glm::vec4(v, 0.0f), glm::vec4(glm::vec3(0.0f, 0.0f, 0.0f), 1.0f))); currentSpine2Pose.trans() = rigSpine2.trans(); - qCDebug(animation) << "my skeleton model spline spine2 " << rigSpine2.trans(); - qCDebug(animation) << "my skeleton model current spine2 " << currentSpine2Pose.trans(); - // qCDebug(animation) << "my skeleton model spline hips " << sensorToRigPose * sensorHips; - // qCDebug(animation) << "my skeleton model current hips " << currentHipsPose.trans(); currentSpine2Pose.rot() = safeLerp(currentSpine2Pose.rot(), newSpinePose.rot(), SPINE2_ROTATION_FILTER); params.primaryControllerPoses[Rig::PrimaryControllerType_Spine2] = currentSpine2Pose; params.primaryControllerFlags[Rig::PrimaryControllerType_Spine2] = (uint8_t)Rig::ControllerFlags::Enabled | (uint8_t)Rig::ControllerFlags::Estimated; diff --git a/libraries/animation/src/AnimSplineIK.cpp b/libraries/animation/src/AnimSplineIK.cpp index 3aca678fa3..0cd646097c 100644 --- a/libraries/animation/src/AnimSplineIK.cpp +++ b/libraries/animation/src/AnimSplineIK.cpp @@ -199,8 +199,6 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const AnimPose midTargetPose(midTarget.getRotation(), midTarget.getTranslation()); //_poses[childOfMiddleJointIndex] = midTargetPose.inverse() * childOfMiddleJointAbsolutePoseAfterBaseTipSpline; } - - _splineJointInfoMap.clear(); AnimChain upperJointChain; AnimPoseVec finalAbsolutePoses; From e36877a86139cd6df4f2420f55931d2d6ff64df8 Mon Sep 17 00:00:00 2001 From: Angus Antley Date: Tue, 29 Jan 2019 22:02:32 -0800 Subject: [PATCH 032/112] added the interp for the possibility of extra flex coeffs --- libraries/animation/src/AnimSplineIK.cpp | 172 +++++++++-------------- libraries/animation/src/AnimSplineIK.h | 8 +- libraries/animation/src/IKTarget.h | 3 +- 3 files changed, 68 insertions(+), 115 deletions(-) diff --git a/libraries/animation/src/AnimSplineIK.cpp b/libraries/animation/src/AnimSplineIK.cpp index 0cd646097c..b9dd1b4f07 100644 --- a/libraries/animation/src/AnimSplineIK.cpp +++ b/libraries/animation/src/AnimSplineIK.cpp @@ -72,6 +72,7 @@ AnimSplineIK::~AnimSplineIK() { } const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const AnimContext& context, float dt, AnimVariantMap& triggersOut) { + assert(_children.size() == 1); if (_children.size() != 1) { return _poses; @@ -85,7 +86,7 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const AnimPoseVec underPoses = _children[0]->evaluate(animVars, context, dt, triggersOut); // if we don't have a skeleton, or jointName lookup failed or the spline alpha is 0 or there are no underposes. - if (!_skeleton || _baseJointIndex == -1 || _tipJointIndex == -1 || alpha == 0.0f || underPoses.size() == 0) { + if (!_skeleton || _baseJointIndex == -1 || _midJointIndex == -1 || _tipJointIndex == -1 || alpha == 0.0f || underPoses.size() == 0) { // pass underPoses through unmodified. _poses = underPoses; return _poses; @@ -136,6 +137,28 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const _poses[_baseJointIndex] = baseParentAbsPose.inverse() * baseTargetAbsolutePose; _poses[_baseJointIndex].scale() = glm::vec3(1.0f); + + + // initialize the middle joint target + IKTarget midTarget; + midTarget.setType((int)IKTarget::Type::Spline); + midTarget.setIndex(_midJointIndex); + AnimPose absPoseMid = _skeleton->getAbsolutePose(_midJointIndex, _poses); + glm::quat midTargetRotation = animVars.lookupRigToGeometry(_midRotationVar, absPoseMid.rot()); + glm::vec3 midTargetPosition = animVars.lookupRigToGeometry(_midPositionVar, absPoseMid.trans()); + midTarget.setPose(midTargetRotation, midTargetPosition); + midTarget.setWeight(1.0f); + midTarget.setFlexCoefficients(_numMidTargetFlexCoefficients, _midTargetFlexCoefficients); + + // solve the lower spine spline + AnimChain midJointChain; + AnimPoseVec absolutePosesAfterBaseTipSpline; + absolutePosesAfterBaseTipSpline.resize(_poses.size()); + computeAbsolutePoses(absolutePosesAfterBaseTipSpline); + midJointChain.buildFromRelativePoses(_skeleton, _poses, midTarget.getIndex()); + solveTargetWithSpline(context, _baseJointIndex, midTarget, absolutePosesAfterBaseTipSpline, context.getEnableDebugDrawIKChains(), midJointChain); + midJointChain.outputRelativePoses(_poses); + // initialize the tip target IKTarget tipTarget; tipTarget.setType((int)IKTarget::Type::Spline); @@ -147,72 +170,15 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const tipTarget.setWeight(1.0f); tipTarget.setFlexCoefficients(_numTipTargetFlexCoefficients, _tipTargetFlexCoefficients); - /* - AnimChain jointChain; - AnimPoseVec absolutePoses; - absolutePoses.resize(_poses.size()); - computeAbsolutePoses(absolutePoses); - jointChain.buildFromRelativePoses(_skeleton, _poses, tipTarget.getIndex()); - solveTargetWithSpline(context, _baseJointIndex, tipTarget, absolutePoses, context.getEnableDebugDrawIKChains(), jointChain); - jointChain.buildDirtyAbsolutePoses(); - jointChain.outputRelativePoses(_poses); - */ - - IKTarget midTarget; - if (_midJointIndex != -1) { - - // initialize the middle joint target - midTarget.setType((int)IKTarget::Type::Spline); - midTarget.setIndex(_midJointIndex); - // set the middle joint to the position that was just determined by the base-tip spline. - AnimPose afterSolveMidTarget = _skeleton->getAbsolutePose(_midJointIndex, _poses); - // use the rotation from the ik target value, if there is one. - glm::quat midTargetRotation = animVars.lookupRigToGeometry(_midRotationVar, afterSolveMidTarget.rot()); - glm::vec3 midTargetPosition = animVars.lookupRigToGeometry(_midPositionVar, afterSolveMidTarget.trans()); - AnimPose updatedMidTarget = AnimPose(midTargetRotation, midTargetPosition); - //qCDebug(animation) << "spine2 in AnimSpline " << updatedMidTarget.trans(); - midTarget.setPose(updatedMidTarget.rot(), updatedMidTarget.trans()); - midTarget.setWeight(1.0f); - midTarget.setFlexCoefficients(_numMidTargetFlexCoefficients, _midTargetFlexCoefficients); - - AnimChain midJointChain; - // Find the pose of the middle target's child. This is to correct the mid to tip - // after the base to mid spline is set. - int childOfMiddleJointIndex = -1; - AnimPose childOfMiddleJointAbsolutePoseAfterBaseTipSpline; - childOfMiddleJointIndex = _tipJointIndex; - while ((_skeleton->getParentIndex(childOfMiddleJointIndex) != _midJointIndex) && (childOfMiddleJointIndex != -1)) { - childOfMiddleJointIndex = _skeleton->getParentIndex(childOfMiddleJointIndex); - } - // if the middle joint is not actually between the base and the tip then don't create spline for it - if (childOfMiddleJointIndex != -1) { - childOfMiddleJointAbsolutePoseAfterBaseTipSpline = _skeleton->getAbsolutePose(childOfMiddleJointIndex, _poses); - - AnimPoseVec absolutePosesAfterBaseTipSpline; - absolutePosesAfterBaseTipSpline.resize(_poses.size()); - computeAbsolutePoses(absolutePosesAfterBaseTipSpline); - midJointChain.buildFromRelativePoses(_skeleton, _poses, midTarget.getIndex()); - solveTargetWithSpline(context, _baseJointIndex, midTarget, absolutePosesAfterBaseTipSpline, context.getEnableDebugDrawIKChains(), midJointChain); - midJointChain.outputRelativePoses(_poses); - - // set the mid to tip segment to match the absolute rotation of the tip target. - AnimPose midTargetPose(midTarget.getRotation(), midTarget.getTranslation()); - //_poses[childOfMiddleJointIndex] = midTargetPose.inverse() * childOfMiddleJointAbsolutePoseAfterBaseTipSpline; - } - - AnimChain upperJointChain; - AnimPoseVec finalAbsolutePoses; - finalAbsolutePoses.resize(_poses.size()); - computeAbsolutePoses(finalAbsolutePoses); - upperJointChain.buildFromRelativePoses(_skeleton, _poses, tipTarget.getIndex()); - solveTargetWithSpline(context, _midJointIndex, tipTarget, finalAbsolutePoses, context.getEnableDebugDrawIKChains(), upperJointChain); - upperJointChain.buildDirtyAbsolutePoses(); - upperJointChain.outputRelativePoses(_poses); - - } - - - + // solve the upper spine spline + AnimChain upperJointChain; + AnimPoseVec finalAbsolutePoses; + finalAbsolutePoses.resize(_poses.size()); + computeAbsolutePoses(finalAbsolutePoses); + upperJointChain.buildFromRelativePoses(_skeleton, _poses, tipTarget.getIndex()); + solveTargetWithSpline(context, _midJointIndex, tipTarget, finalAbsolutePoses, context.getEnableDebugDrawIKChains(), upperJointChain); + upperJointChain.buildDirtyAbsolutePoses(); + upperJointChain.outputRelativePoses(_poses); // compute chain AnimChain ikChain; @@ -279,17 +245,14 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const } else if (context.getEnableDebugDrawIKTargets() != _previousEnableDebugIKTargets) { + // remove markers if they were added last frame. - QString name = QString("ikTargetSplineTip"); DebugDraw::getInstance().removeMyAvatarMarker(name); - if (_midJointIndex != -1) { - QString name2 = QString("ikTargetSplineMid"); - DebugDraw::getInstance().removeMyAvatarMarker(name2); - } + QString name2 = QString("ikTargetSplineMid"); + DebugDraw::getInstance().removeMyAvatarMarker(name2); QString name3 = QString("ikTargetSplineBase"); DebugDraw::getInstance().removeMyAvatarMarker(name3); - } _previousEnableDebugIKTargets = context.getEnableDebugDrawIKTargets(); @@ -306,10 +269,6 @@ void AnimSplineIK::lookUpIndices() { _baseJointIndex = indices[0]; _tipJointIndex = indices[1]; _midJointIndex = indices[2]; - - if (_baseJointIndex != -1) { - _baseParentJointIndex = _skeleton->getParentIndex(_baseJointIndex); - } } void AnimSplineIK::computeAbsolutePoses(AnimPoseVec& absolutePoses) const { @@ -348,11 +307,9 @@ static CubicHermiteSplineFunctorWithArcLength computeSplineFromTipAndBase(const void AnimSplineIK::solveTargetWithSpline(const AnimContext& context, int base, const IKTarget& target, const AnimPoseVec& absolutePoses, bool debug, AnimChain& chainInfoOut) const { - const int baseIndex = base; - // build spline from tip to base AnimPose tipPose = AnimPose(glm::vec3(1.0f), target.getRotation(), target.getTranslation()); - AnimPose basePose = absolutePoses[baseIndex]; + AnimPose basePose = absolutePoses[base]; CubicHermiteSplineFunctorWithArcLength spline; if (target.getIndex() == _tipJointIndex) { @@ -371,13 +328,12 @@ void AnimSplineIK::solveTargetWithSpline(const AnimContext& context, int base, c if (glm::dot(halfRot * Vectors::UNIT_Z, basePose.rot() * Vectors::UNIT_Z) < 0.0f) { tipPose.rot() = -tipPose.rot(); } + // find or create splineJointInfo for this target const std::vector* splineJointInfoVec = findOrCreateSplineJointInfo(context, base, target); - //qCDebug(animation) << "the size of the splineJointInfo is " << splineJointInfoVec->size() << " and the base index is "<size() > 0) { - const int baseParentIndex = _skeleton->getParentIndex(baseIndex); + const int baseParentIndex = _skeleton->getParentIndex(base); AnimPose parentAbsPose = (baseParentIndex >= 0) ? absolutePoses[baseParentIndex] : AnimPose(); // go thru splineJointInfoVec backwards (base to tip) for (int i = (int)splineJointInfoVec->size() - 1; i >= 0; i--) { @@ -404,10 +360,27 @@ void AnimSplineIK::solveTargetWithSpline(const AnimContext& context, int base, c // apply flex coefficent AnimPose flexedAbsPose; - ::blend(1, &absolutePoses[splineJointInfo.jointIndex], &desiredAbsPose, target.getFlexCoefficient(i), &flexedAbsPose); - + // get the number of flex coeff for this spline + float interpedCoefficient = 1.0f; + int numFlexCoeff = target.getNumFlexCoefficients(); + if (numFlexCoeff == splineJointInfoVec->size()) { + // then do nothing special + interpedCoefficient = target.getFlexCoefficient(i); + } else { + // interp based on ratio of the joint. + if (splineJointInfo.ratio < 1.0f) { + float flexInterp = splineJointInfo.ratio * (float)(numFlexCoeff - 1); + int startCoeff = floor(flexInterp); + float partial = flexInterp - startCoeff; + interpedCoefficient = target.getFlexCoefficient(startCoeff) * (1 - partial) + target.getFlexCoefficient(startCoeff + 1) * partial; + } else { + interpedCoefficient = target.getFlexCoefficient(numFlexCoeff - 1); + } + } + ::blend(1, &absolutePoses[splineJointInfo.jointIndex], &desiredAbsPose, interpedCoefficient, &flexedAbsPose); + AnimPose relPose = parentAbsPose.inverse() * flexedAbsPose; - /* + bool constrained = false; if (splineJointInfo.jointIndex != base) { // constrain the amount the spine can stretch or compress @@ -429,7 +402,7 @@ void AnimSplineIK::solveTargetWithSpline(const AnimContext& context, int base, c relPose.trans() = glm::vec3(0.0f); } } - */ + if (!chainInfoOut.setRelativePoseAtJointIndex(splineJointInfo.jointIndex, relPose)) { qCDebug(animation) << "we didn't find the joint index for the spline!!!!"; } @@ -463,8 +436,6 @@ const std::vector* AnimSplineIK::findOrCreateSpli void AnimSplineIK::computeAndCacheSplineJointInfosForIKTarget(const AnimContext& context, int base, const IKTarget& target) const { std::vector splineJointInfoVec; - //qCDebug(animation) << "the base in compute cache is " << base; - // build spline between the default poses. AnimPose tipPose = _skeleton->getAbsoluteDefaultPose(target.getIndex()); AnimPose basePose = _skeleton->getAbsoluteDefaultPose(base); @@ -478,7 +449,6 @@ void AnimSplineIK::computeAndCacheSplineJointInfosForIKTarget(const AnimContext& } else { spline = computeSplineFromTipAndBase(tipPose, basePose); } - // measure the total arc length along the spline float totalArcLength = spline.arcLength(1.0f); @@ -487,17 +457,12 @@ void AnimSplineIK::computeAndCacheSplineJointInfosForIKTarget(const AnimContext& glm::vec3 baseToTipNormal = baseToTip / baseToTipLength; int index = target.getIndex(); - int endIndex; - // fix this statement. AA - if (target.getIndex() == _tipJointIndex) { - endIndex = _skeleton->getParentIndex(base); - } else { - endIndex = _skeleton->getParentIndex(base); - } + int endIndex = _skeleton->getParentIndex(base); + while (index != endIndex) { AnimPose defaultPose = _skeleton->getAbsoluteDefaultPose(index); - - float ratio = glm::dot(defaultPose.trans() - basePose.trans(), baseToTipNormal) / baseToTipLength; + glm::vec3 baseToCurrentJoint = defaultPose.trans() - basePose.trans(); + float ratio = glm::dot(baseToCurrentJoint, baseToTipNormal) / baseToTipLength; // compute offset from spline to the default pose. float t = spline.arcLengthInverse(ratio * totalArcLength); @@ -520,15 +485,6 @@ void AnimSplineIK::computeAndCacheSplineJointInfosForIKTarget(const AnimContext& _splineJointInfoMap[target.getIndex()] = splineJointInfoVec; } -void AnimSplineIK::loadPoses(const AnimPoseVec& poses) { - assert(_skeleton && ((poses.size() == 0) || (_skeleton->getNumJoints() == (int)poses.size()))); - if (_skeleton->getNumJoints() == (int)poses.size()) { - _poses = poses; - } else { - _poses.clear(); - } -} - void AnimSplineIK::beginInterp(InterpType interpType, const AnimChain& chain) { // capture the current poses in a snapshot. _snapshotChain = chain; diff --git a/libraries/animation/src/AnimSplineIK.h b/libraries/animation/src/AnimSplineIK.h index d664cf37a4..ee3f29d6df 100644 --- a/libraries/animation/src/AnimSplineIK.h +++ b/libraries/animation/src/AnimSplineIK.h @@ -63,6 +63,8 @@ protected: QString _midRotationVar; QString _tipPositionVar; QString _tipRotationVar; + QString _alphaVar; // float - (0, 1) 0 means underPoses only, 1 means IK only. + QString _enabledVar; static const int MAX_NUMBER_FLEX_VARIABLES = 10; float _tipTargetFlexCoefficients[MAX_NUMBER_FLEX_VARIABLES]; @@ -70,20 +72,15 @@ protected: int _numTipTargetFlexCoefficients { 0 }; int _numMidTargetFlexCoefficients { 0 }; - int _baseParentJointIndex { -1 }; int _baseJointIndex { -1 }; int _midJointIndex { -1 }; int _tipJointIndex { -1 }; - QString _alphaVar; // float - (0, 1) 0 means underPoses only, 1 means IK only. - QString _enabledVar; // bool - bool _previousEnableDebugIKTargets { false }; InterpType _interpType{ InterpType::None }; float _interpAlphaVel{ 0.0f }; float _interpAlpha{ 0.0f }; - AnimChain _snapshotChain; // used to pre-compute information about each joint influenced by a spline IK target. @@ -93,7 +90,6 @@ protected: AnimPose offsetPose; // local offset from the spline to the joint. }; - bool _lastEnableDebugDrawIKTargets { false }; void AnimSplineIK::solveTargetWithSpline(const AnimContext& context, int base, const IKTarget& target, const AnimPoseVec& absolutePoses, bool debug, AnimChain& chainInfoOut) const; void computeAndCacheSplineJointInfosForIKTarget(const AnimContext& context, int base, const IKTarget& target) const; const std::vector* findOrCreateSplineJointInfo(const AnimContext& context, int base, const IKTarget& target) const; diff --git a/libraries/animation/src/IKTarget.h b/libraries/animation/src/IKTarget.h index 325a1b40b6..5c77b3c29a 100644 --- a/libraries/animation/src/IKTarget.h +++ b/libraries/animation/src/IKTarget.h @@ -35,6 +35,8 @@ public: bool getPoleVectorEnabled() const { return _poleVectorEnabled; } int getIndex() const { return _index; } Type getType() const { return _type; } + int getNumFlexCoefficients() const { return _numFlexCoefficients; } + float getFlexCoefficient(size_t chainDepth) const; void setPose(const glm::quat& rotation, const glm::vec3& translation); void setPoleVector(const glm::vec3& poleVector) { _poleVector = poleVector; } @@ -43,7 +45,6 @@ public: void setIndex(int index) { _index = index; } void setType(int); void setFlexCoefficients(size_t numFlexCoefficientsIn, const float* flexCoefficientsIn); - float getFlexCoefficient(size_t chainDepth) const; void setWeight(float weight) { _weight = weight; } float getWeight() const { return _weight; } From 2e1a4545c6dde3b4586a160e95132ae8c8405f01 Mon Sep 17 00:00:00 2001 From: amantley Date: Wed, 30 Jan 2019 14:47:03 -0800 Subject: [PATCH 033/112] cache the spine2 spline default offset and ratio --- interface/src/avatar/MySkeletonModel.cpp | 52 ++++++++++++++----- .../src/avatars-renderer/Avatar.cpp | 46 ++++++++++++++++ .../src/avatars-renderer/Avatar.h | 9 ++++ libraries/shared/src/AvatarConstants.h | 1 + 4 files changed, 94 insertions(+), 14 deletions(-) diff --git a/interface/src/avatar/MySkeletonModel.cpp b/interface/src/avatar/MySkeletonModel.cpp index 38f18d2ac9..e77f74de47 100755 --- a/interface/src/avatar/MySkeletonModel.cpp +++ b/interface/src/avatar/MySkeletonModel.cpp @@ -44,25 +44,46 @@ static CubicHermiteSplineFunctorWithArcLength computeSplineFromTipAndBase(const } static glm::vec3 computeSpine2WithHeadHipsSpline(MyAvatar* myAvatar, AnimPose hipsIKTargetPose, AnimPose headIKTargetPose) { - glm::vec3 basePosition = myAvatar->getAbsoluteDefaultJointTranslationInObjectFrame(myAvatar->getJointIndex("Hips")); - glm::vec3 tipPosition = myAvatar->getAbsoluteDefaultJointTranslationInObjectFrame(myAvatar->getJointIndex("Head")); - glm::vec3 spine2Position = myAvatar->getAbsoluteDefaultJointTranslationInObjectFrame(myAvatar->getJointIndex("Spine2")); + /* + AnimPose avatarToRigPose(glm::vec3(1.0f), Quaternions::Y_180, glm::vec3(0.0f)); + + AnimPose hipsDefaultPoseAvatarSpace(myAvatar->getAbsoluteDefaultJointRotationInObjectFrame(myAvatar->getJointIndex("Hips")), myAvatar->getAbsoluteDefaultJointTranslationInObjectFrame(myAvatar->getJointIndex("Hips"))); + AnimPose headDefaultPoseAvatarSpace(myAvatar->getAbsoluteDefaultJointRotationInObjectFrame(myAvatar->getJointIndex("Head")), myAvatar->getAbsoluteDefaultJointTranslationInObjectFrame(myAvatar->getJointIndex("Head"))); + AnimPose spine2DefaultPoseAvatarSpace(myAvatar->getAbsoluteDefaultJointRotationInObjectFrame(myAvatar->getJointIndex("Spine2")), myAvatar->getAbsoluteDefaultJointTranslationInObjectFrame(myAvatar->getJointIndex("Spine2"))); + AnimPose hipsDefaultPoseRigSpace = avatarToRigPose * hipsDefaultPoseAvatarSpace; + AnimPose headDefaultPoseRigSpace = avatarToRigPose * headDefaultPoseAvatarSpace; + AnimPose spine2DefaultPoseRigSpace = avatarToRigPose * spine2DefaultPoseAvatarSpace; + + + glm::vec3 basePosition = hipsDefaultPoseRigSpace.trans(); + glm::vec3 tipPosition = headDefaultPoseRigSpace.trans(); + glm::vec3 spine2Position = spine2DefaultPoseRigSpace.trans(); glm::vec3 baseToTip = tipPosition - basePosition; float baseToTipLength = glm::length(baseToTip); glm::vec3 baseToTipNormal = baseToTip / baseToTipLength; glm::vec3 baseToSpine2 = spine2Position - basePosition; float ratio = glm::dot(baseToSpine2, baseToTipNormal) / baseToTipLength; + CubicHermiteSplineFunctorWithArcLength defaultSpline = computeSplineFromTipAndBase(headDefaultPoseRigSpace, hipsDefaultPoseRigSpace); + // measure the total arc length along the spline + float totalDefaultArcLength = defaultSpline.arcLength(1.0f); + float t = defaultSpline.arcLengthInverse(ratio * totalDefaultArcLength); + glm::vec3 defaultSplineSpine2Translation = defaultSpline(t); + + glm::vec3 offset = spine2Position - defaultSplineSpine2Translation; + + qCDebug(animation) << "the my skeleton model numbers are " << ratio << " and " << offset; + */ // the the ik targets to compute the spline with - CubicHermiteSplineFunctorWithArcLength spline = computeSplineFromTipAndBase(headIKTargetPose, hipsIKTargetPose); + CubicHermiteSplineFunctorWithArcLength splineFinal = computeSplineFromTipAndBase(headIKTargetPose, hipsIKTargetPose); // measure the total arc length along the spline - float totalArcLength = spline.arcLength(1.0f); - float t = spline.arcLengthInverse(ratio * totalArcLength); + float totalArcLength = splineFinal.arcLength(1.0f); + float tFinal = splineFinal.arcLengthInverse(myAvatar->getSpine2SplineRatio() * totalArcLength); - glm::vec3 spine2Translation = spline(t); + glm::vec3 spine2Translation = splineFinal(tFinal); - return spine2Translation; + return spine2Translation + myAvatar->getSpine2SplineOffset(); } @@ -266,11 +287,14 @@ void MySkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) { myAvatar->getControllerPoseInAvatarFrame(controller::Action::LEFT_HAND).isValid() && !(params.primaryControllerFlags[Rig::PrimaryControllerType_Spine2] & (uint8_t)Rig::ControllerFlags::Enabled)) { - controller::Pose headSplineControllerPose = myAvatar->getControllerPoseInSensorFrame(controller::Action::HEAD); - AnimPose headSplinePose(headSplineControllerPose.getRotation(), headSplineControllerPose.getTranslation()); - glm::vec3 spine2TargetTranslation = computeSpine2WithHeadHipsSpline(myAvatar, sensorHips, headSplinePose); - AnimPose sensorSpine2(Quaternions::IDENTITY, spine2TargetTranslation); - AnimPose rigSpine2 = sensorToRigPose * sensorSpine2; + // if (avatarHeadPose.isValid()) { + + AnimPose headAvatarSpace(avatarHeadPose.getRotation(), avatarHeadPose.getTranslation()); + AnimPose headRigSpace = avatarToRigPose * headAvatarSpace; + AnimPose hipsRigSpace = sensorToRigPose * sensorHips; + glm::vec3 spine2TargetTranslation = computeSpine2WithHeadHipsSpline(myAvatar, hipsRigSpace, headRigSpace); + //AnimPose rigSpine2(Quaternions::IDENTITY, spine2TargetTranslation); + //AnimPose rigSpine2 = sensorToRigPose * sensorSpine2; const float SPINE2_ROTATION_FILTER = 0.5f; AnimPose currentSpine2Pose; @@ -292,7 +316,7 @@ void MySkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) { } generateBasisVectors(up, fwd, u, v, w); AnimPose newSpinePose(glm::mat4(glm::vec4(w, 0.0f), glm::vec4(u, 0.0f), glm::vec4(v, 0.0f), glm::vec4(glm::vec3(0.0f, 0.0f, 0.0f), 1.0f))); - currentSpine2Pose.trans() = rigSpine2.trans(); + currentSpine2Pose.trans() = spine2TargetTranslation; currentSpine2Pose.rot() = safeLerp(currentSpine2Pose.rot(), newSpinePose.rot(), SPINE2_ROTATION_FILTER); params.primaryControllerPoses[Rig::PrimaryControllerType_Spine2] = currentSpine2Pose; params.primaryControllerFlags[Rig::PrimaryControllerType_Spine2] = (uint8_t)Rig::ControllerFlags::Enabled | (uint8_t)Rig::ControllerFlags::Estimated; diff --git a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp index 17d10cdf49..1ae53e2023 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp +++ b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp @@ -1420,11 +1420,13 @@ void Avatar::setModelURLFinished(bool success) { // rig is ready void Avatar::rigReady() { buildUnscaledEyeHeightCache(); + buildSpine2SplineRatioCache(); } // rig has been reset. void Avatar::rigReset() { clearUnscaledEyeHeightCache(); + clearSpine2SplineRatioCache(); } // create new model, can return an instance of a SoftAttachmentModel rather then Model @@ -1821,10 +1823,54 @@ void Avatar::buildUnscaledEyeHeightCache() { } } +static CubicHermiteSplineFunctorWithArcLength computeSplineFromTipAndBase(const AnimPose& tipPose, const AnimPose& basePose, float baseGain = 1.0f, float tipGain = 1.0f) { + float linearDistance = glm::length(basePose.trans() - tipPose.trans()); + glm::vec3 p0 = basePose.trans(); + glm::vec3 m0 = baseGain * linearDistance * (basePose.rot() * Vectors::UNIT_Y); + glm::vec3 p1 = tipPose.trans(); + glm::vec3 m1 = tipGain * linearDistance * (tipPose.rot() * Vectors::UNIT_Y); + + return CubicHermiteSplineFunctorWithArcLength(p0, m0, p1, m1); +} + +void Avatar::buildSpine2SplineRatioCache() { + if (_skeletonModel) { + auto& rig = _skeletonModel->getRig(); + AnimPose hipsRigDefaultPose = rig.getAbsoluteDefaultPose(rig.indexOfJoint("Hips")); + AnimPose headRigDefaultPose(rig.getAbsoluteDefaultPose(rig.indexOfJoint("Head"))); + glm::vec3 basePosition = hipsRigDefaultPose.trans(); + glm::vec3 tipPosition = headRigDefaultPose.trans(); + glm::vec3 spine2Position = rig.getAbsoluteDefaultPose(rig.indexOfJoint("Spine2")).trans(); + + glm::vec3 baseToTip = tipPosition - basePosition; + float baseToTipLength = glm::length(baseToTip); + glm::vec3 baseToTipNormal = baseToTip / baseToTipLength; + glm::vec3 baseToSpine2 = spine2Position - basePosition; + + _spine2SplineRatio = glm::dot(baseToSpine2, baseToTipNormal) / baseToTipLength; + + CubicHermiteSplineFunctorWithArcLength defaultSpline = computeSplineFromTipAndBase(headRigDefaultPose, hipsRigDefaultPose); + // measure the total arc length along the spline + float totalDefaultArcLength = defaultSpline.arcLength(1.0f); + float t = defaultSpline.arcLengthInverse(_spine2SplineRatio * totalDefaultArcLength); + glm::vec3 defaultSplineSpine2Translation = defaultSpline(t); + + _spine2SplineOffset = spine2Position - defaultSplineSpine2Translation; + + qCDebug(avatars_renderer) << "the avatar spline numbers are " << _spine2SplineRatio << " and " << _spine2SplineOffset; + } + +} + void Avatar::clearUnscaledEyeHeightCache() { _unscaledEyeHeightCache.set(DEFAULT_AVATAR_EYE_HEIGHT); } +void Avatar::clearSpine2SplineRatioCache() { + _spine2SplineRatio = DEFAULT_AVATAR_EYE_HEIGHT; + _spine2SplineOffset = glm::vec3(); +} + float Avatar::getUnscaledEyeHeightFromSkeleton() const { // TODO: if performance becomes a concern we can cache this value rather then computing it everytime. diff --git a/libraries/avatars-renderer/src/avatars-renderer/Avatar.h b/libraries/avatars-renderer/src/avatars-renderer/Avatar.h index d5431ad2d2..acfcdc4ee4 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/Avatar.h +++ b/libraries/avatars-renderer/src/avatars-renderer/Avatar.h @@ -22,6 +22,7 @@ #include #include #include +#include #include "Head.h" #include "SkeletonModel.h" @@ -228,6 +229,9 @@ public: virtual bool setAbsoluteJointRotationInObjectFrame(int index, const glm::quat& rotation) override { return false; } virtual bool setAbsoluteJointTranslationInObjectFrame(int index, const glm::vec3& translation) override { return false; } + virtual glm::vec3 getSpine2SplineOffset() const { return _spine2SplineOffset; } + virtual float getSpine2SplineRatio() const { return _spine2SplineRatio; } + virtual void setSkeletonModelURL(const QUrl& skeletonModelURL) override; virtual void setAttachmentData(const QVector& attachmentData) override; @@ -499,7 +503,9 @@ public slots: protected: float getUnscaledEyeHeightFromSkeleton() const; void buildUnscaledEyeHeightCache(); + void buildSpine2SplineRatioCache(); void clearUnscaledEyeHeightCache(); + void clearSpine2SplineRatioCache(); virtual const QString& getSessionDisplayNameForTransport() const override { return _empty; } // Save a tiny bit of bandwidth. Mixer won't look at what we send. QString _empty{}; virtual void maybeUpdateSessionDisplayNameFromTransport(const QString& sessionDisplayName) override { _sessionDisplayName = sessionDisplayName; } // don't use no-op setter! @@ -552,6 +558,7 @@ protected: float getHeadHeight() const; float getPelvisFloatingHeight() const; glm::vec3 getDisplayNamePosition() const; + Transform calculateDisplayNameTransform(const ViewFrustum& view, const glm::vec3& textPosition) const; void renderDisplayName(gpu::Batch& batch, const ViewFrustum& view, const glm::vec3& textPosition) const; @@ -607,6 +614,8 @@ protected: float _displayNameAlpha { 1.0f }; ThreadSafeValueCache _unscaledEyeHeightCache { DEFAULT_AVATAR_EYE_HEIGHT }; + float _spine2SplineRatio { DEFAULT_SPINE2_SPLINE_PROPORTION }; + glm::vec3 _spine2SplineOffset; std::unordered_map _materials; std::mutex _materialsLock; diff --git a/libraries/shared/src/AvatarConstants.h b/libraries/shared/src/AvatarConstants.h index 87da47a27a..9b0ff678e6 100644 --- a/libraries/shared/src/AvatarConstants.h +++ b/libraries/shared/src/AvatarConstants.h @@ -20,6 +20,7 @@ const float DEFAULT_AVATAR_EYE_TO_TOP_OF_HEAD = 0.11f; // meters const float DEFAULT_AVATAR_NECK_TO_TOP_OF_HEAD = 0.185f; // meters const float DEFAULT_AVATAR_NECK_HEIGHT = DEFAULT_AVATAR_HEIGHT - DEFAULT_AVATAR_NECK_TO_TOP_OF_HEAD; const float DEFAULT_AVATAR_EYE_HEIGHT = DEFAULT_AVATAR_HEIGHT - DEFAULT_AVATAR_EYE_TO_TOP_OF_HEAD; +const float DEFAULT_SPINE2_SPLINE_PROPORTION = 0.75f; const float DEFAULT_AVATAR_SUPPORT_BASE_LEFT = -0.25f; const float DEFAULT_AVATAR_SUPPORT_BASE_RIGHT = 0.25f; const float DEFAULT_AVATAR_SUPPORT_BASE_FRONT = -0.20f; From 7a1c1252ff336df24c2c6e0764137c8e854709c0 Mon Sep 17 00:00:00 2001 From: amantley Date: Wed, 30 Jan 2019 16:09:10 -0800 Subject: [PATCH 034/112] cleanup --- interface/src/avatar/MySkeletonModel.cpp | 36 +------------------ .../src/avatars-renderer/Avatar.cpp | 1 + 2 files changed, 2 insertions(+), 35 deletions(-) diff --git a/interface/src/avatar/MySkeletonModel.cpp b/interface/src/avatar/MySkeletonModel.cpp index e77f74de47..f4cfb79314 100755 --- a/interface/src/avatar/MySkeletonModel.cpp +++ b/interface/src/avatar/MySkeletonModel.cpp @@ -44,43 +44,13 @@ static CubicHermiteSplineFunctorWithArcLength computeSplineFromTipAndBase(const } static glm::vec3 computeSpine2WithHeadHipsSpline(MyAvatar* myAvatar, AnimPose hipsIKTargetPose, AnimPose headIKTargetPose) { - /* - AnimPose avatarToRigPose(glm::vec3(1.0f), Quaternions::Y_180, glm::vec3(0.0f)); - - AnimPose hipsDefaultPoseAvatarSpace(myAvatar->getAbsoluteDefaultJointRotationInObjectFrame(myAvatar->getJointIndex("Hips")), myAvatar->getAbsoluteDefaultJointTranslationInObjectFrame(myAvatar->getJointIndex("Hips"))); - AnimPose headDefaultPoseAvatarSpace(myAvatar->getAbsoluteDefaultJointRotationInObjectFrame(myAvatar->getJointIndex("Head")), myAvatar->getAbsoluteDefaultJointTranslationInObjectFrame(myAvatar->getJointIndex("Head"))); - AnimPose spine2DefaultPoseAvatarSpace(myAvatar->getAbsoluteDefaultJointRotationInObjectFrame(myAvatar->getJointIndex("Spine2")), myAvatar->getAbsoluteDefaultJointTranslationInObjectFrame(myAvatar->getJointIndex("Spine2"))); - AnimPose hipsDefaultPoseRigSpace = avatarToRigPose * hipsDefaultPoseAvatarSpace; - AnimPose headDefaultPoseRigSpace = avatarToRigPose * headDefaultPoseAvatarSpace; - AnimPose spine2DefaultPoseRigSpace = avatarToRigPose * spine2DefaultPoseAvatarSpace; - - - glm::vec3 basePosition = hipsDefaultPoseRigSpace.trans(); - glm::vec3 tipPosition = headDefaultPoseRigSpace.trans(); - glm::vec3 spine2Position = spine2DefaultPoseRigSpace.trans(); - glm::vec3 baseToTip = tipPosition - basePosition; - float baseToTipLength = glm::length(baseToTip); - glm::vec3 baseToTipNormal = baseToTip / baseToTipLength; - glm::vec3 baseToSpine2 = spine2Position - basePosition; - float ratio = glm::dot(baseToSpine2, baseToTipNormal) / baseToTipLength; - - CubicHermiteSplineFunctorWithArcLength defaultSpline = computeSplineFromTipAndBase(headDefaultPoseRigSpace, hipsDefaultPoseRigSpace); - // measure the total arc length along the spline - float totalDefaultArcLength = defaultSpline.arcLength(1.0f); - float t = defaultSpline.arcLengthInverse(ratio * totalDefaultArcLength); - glm::vec3 defaultSplineSpine2Translation = defaultSpline(t); - - glm::vec3 offset = spine2Position - defaultSplineSpine2Translation; - - qCDebug(animation) << "the my skeleton model numbers are " << ratio << " and " << offset; - */ + // the the ik targets to compute the spline with CubicHermiteSplineFunctorWithArcLength splineFinal = computeSplineFromTipAndBase(headIKTargetPose, hipsIKTargetPose); // measure the total arc length along the spline float totalArcLength = splineFinal.arcLength(1.0f); float tFinal = splineFinal.arcLengthInverse(myAvatar->getSpine2SplineRatio() * totalArcLength); - glm::vec3 spine2Translation = splineFinal(tFinal); return spine2Translation + myAvatar->getSpine2SplineOffset(); @@ -287,14 +257,10 @@ void MySkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) { myAvatar->getControllerPoseInAvatarFrame(controller::Action::LEFT_HAND).isValid() && !(params.primaryControllerFlags[Rig::PrimaryControllerType_Spine2] & (uint8_t)Rig::ControllerFlags::Enabled)) { - // if (avatarHeadPose.isValid()) { - AnimPose headAvatarSpace(avatarHeadPose.getRotation(), avatarHeadPose.getTranslation()); AnimPose headRigSpace = avatarToRigPose * headAvatarSpace; AnimPose hipsRigSpace = sensorToRigPose * sensorHips; glm::vec3 spine2TargetTranslation = computeSpine2WithHeadHipsSpline(myAvatar, hipsRigSpace, headRigSpace); - //AnimPose rigSpine2(Quaternions::IDENTITY, spine2TargetTranslation); - //AnimPose rigSpine2 = sensorToRigPose * sensorSpine2; const float SPINE2_ROTATION_FILTER = 0.5f; AnimPose currentSpine2Pose; diff --git a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp index 1ae53e2023..bc2cb8a0ba 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp +++ b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp @@ -1850,6 +1850,7 @@ void Avatar::buildSpine2SplineRatioCache() { _spine2SplineRatio = glm::dot(baseToSpine2, baseToTipNormal) / baseToTipLength; CubicHermiteSplineFunctorWithArcLength defaultSpline = computeSplineFromTipAndBase(headRigDefaultPose, hipsRigDefaultPose); + //CubicHermiteSplineFunctorWithArcLength defaultSpline(headRigDefaultPose, hipsRigDefaultPose); // measure the total arc length along the spline float totalDefaultArcLength = defaultSpline.arcLength(1.0f); float t = defaultSpline.arcLengthInverse(_spine2SplineRatio * totalDefaultArcLength); From 5054b54626e764de0a4cafa290313de5cbf516b5 Mon Sep 17 00:00:00 2001 From: amantley Date: Wed, 30 Jan 2019 16:20:50 -0800 Subject: [PATCH 035/112] removed armIK.cpp and armIK.h, they are for the next changes --- libraries/animation/src/AnimArmIK.cpp | 40 --------------------------- libraries/animation/src/AnimArmIK.h | 34 ----------------------- 2 files changed, 74 deletions(-) delete mode 100644 libraries/animation/src/AnimArmIK.cpp delete mode 100644 libraries/animation/src/AnimArmIK.h diff --git a/libraries/animation/src/AnimArmIK.cpp b/libraries/animation/src/AnimArmIK.cpp deleted file mode 100644 index 202e8c8420..0000000000 --- a/libraries/animation/src/AnimArmIK.cpp +++ /dev/null @@ -1,40 +0,0 @@ -// -// AnimArmIK.cpp -// -// Created by Angus Antley on 1/9/19. -// Copyright (c) 2019 High Fidelity, Inc. All rights reserved. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -#include "AnimArmIK.h" - -#include - -#include "AnimationLogging.h" -#include "AnimUtil.h" - -AnimArmIK::AnimArmIK(const QString& id, float alpha, bool enabled, float interpDuration, - const QString& baseJointName, const QString& midJointName, - const QString& tipJointName, const glm::vec3& midHingeAxis, - const QString& alphaVar, const QString& enabledVar, - const QString& endEffectorRotationVarVar, const QString& endEffectorPositionVarVar) : - AnimTwoBoneIK(id, alpha, enabled, interpDuration, baseJointName, midJointName, tipJointName, midHingeAxis, alphaVar, enabledVar, endEffectorRotationVarVar, endEffectorPositionVarVar) { - -} - -AnimArmIK::~AnimArmIK() { - -} - -const AnimPoseVec& AnimArmIK::evaluate(const AnimVariantMap& animVars, const AnimContext& context, float dt, AnimVariantMap& triggersOut) { - qCDebug(animation) << "evaluating the arm IK"; - - assert(_children.size() == 1); - if (_children.size() != 1) { - return _poses; - } else { - return _poses; - } -} \ No newline at end of file diff --git a/libraries/animation/src/AnimArmIK.h b/libraries/animation/src/AnimArmIK.h deleted file mode 100644 index 26f79a1b9c..0000000000 --- a/libraries/animation/src/AnimArmIK.h +++ /dev/null @@ -1,34 +0,0 @@ -// -// AnimArmIK.h -// -// Created by Angus Antley on 1/9/19. -// Copyright (c) 2019 High Fidelity, Inc. All rights reserved. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -#ifndef hifi_AnimArmIK_h -#define hifi_AnimArmIK_h - -//#include "AnimNode.h" -#include "AnimTwoBoneIK.h" -//#include "AnimChain.h" - -// Simple two bone IK chain -class AnimArmIK : public AnimTwoBoneIK { -public: - AnimArmIK(const QString& id, float alpha, bool enabled, float interpDuration, - const QString& baseJointName, const QString& midJointName, - const QString& tipJointName, const glm::vec3& midHingeAxis, - const QString& alphaVar, const QString& enabledVar, - const QString& endEffectorRotationVarVar, const QString& endEffectorPositionVarVar); - virtual ~AnimArmIK(); - virtual const AnimPoseVec& evaluate(const AnimVariantMap& animVars, const AnimContext& context, float dt, AnimVariantMap& triggersOut) override; - -protected: - -}; - -#endif // hifi_AnimArmIK_h - From d174fb1b5ce17c690a88f9e11a083d1dceec108b Mon Sep 17 00:00:00 2001 From: amantley Date: Wed, 30 Jan 2019 16:59:12 -0800 Subject: [PATCH 036/112] removed print statements --- libraries/animation/src/AnimSplineIK.cpp | 27 +++++++++---------- .../src/avatars-renderer/Avatar.cpp | 4 +-- .../src/avatars-renderer/Avatar.h | 1 - 3 files changed, 13 insertions(+), 19 deletions(-) diff --git a/libraries/animation/src/AnimSplineIK.cpp b/libraries/animation/src/AnimSplineIK.cpp index b9dd1b4f07..e204a8f2d6 100644 --- a/libraries/animation/src/AnimSplineIK.cpp +++ b/libraries/animation/src/AnimSplineIK.cpp @@ -51,15 +51,14 @@ AnimSplineIK::AnimSplineIK(const QString& id, float alpha, bool enabled, float i QStringList tipTargetFlexCoefficientsValues = tipTargetFlexCoefficients.split(',', QString::SkipEmptyParts); for (int i = 0; i < tipTargetFlexCoefficientsValues.size(); i++) { if (i < MAX_NUMBER_FLEX_VARIABLES) { - qCDebug(animation) << "tip target flex value " << tipTargetFlexCoefficientsValues[i].toDouble(); _tipTargetFlexCoefficients[i] = (float)tipTargetFlexCoefficientsValues[i].toDouble(); } } _numTipTargetFlexCoefficients = std::min(tipTargetFlexCoefficientsValues.size(), MAX_NUMBER_FLEX_VARIABLES); + QStringList midTargetFlexCoefficientsValues = midTargetFlexCoefficients.split(',', QString::SkipEmptyParts); for (int i = 0; i < midTargetFlexCoefficientsValues.size(); i++) { if (i < MAX_NUMBER_FLEX_VARIABLES) { - qCDebug(animation) << "mid target flex value " << midTargetFlexCoefficientsValues[i].toDouble(); _midTargetFlexCoefficients[i] = (float)midTargetFlexCoefficientsValues[i].toDouble(); } } @@ -163,10 +162,10 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const IKTarget tipTarget; tipTarget.setType((int)IKTarget::Type::Spline); tipTarget.setIndex(_tipJointIndex); - AnimPose absPose = _skeleton->getAbsolutePose(_tipJointIndex, _poses); - glm::quat rotation = animVars.lookupRigToGeometry(_tipRotationVar, absPose.rot()); - glm::vec3 translation = animVars.lookupRigToGeometry(_tipPositionVar, absPose.trans()); - tipTarget.setPose(rotation, translation); + AnimPose absPoseTip = _skeleton->getAbsolutePose(_tipJointIndex, _poses); + glm::quat tipRotation = animVars.lookupRigToGeometry(_tipRotationVar, absPoseTip.rot()); + glm::vec3 tipTranslation = animVars.lookupRigToGeometry(_tipPositionVar, absPoseTip.trans()); + tipTarget.setPose(tipRotation, tipTranslation); tipTarget.setWeight(1.0f); tipTarget.setFlexCoefficients(_numTipTargetFlexCoefficients, _tipTargetFlexCoefficients); @@ -231,12 +230,10 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const QString name = QString("ikTargetSplineTip"); DebugDraw::getInstance().addMyAvatarMarker(name, glmExtractRotation(avatarTargetMat), extractTranslation(avatarTargetMat), WHITE); - if (_midJointIndex != -1) { - glm::mat4 geomTargetMat2 = createMatFromQuatAndPos(midTarget.getRotation(), midTarget.getTranslation()); - glm::mat4 avatarTargetMat2 = rigToAvatarMat * context.getGeometryToRigMatrix() * geomTargetMat2; - QString name2 = QString("ikTargetSplineMid"); - DebugDraw::getInstance().addMyAvatarMarker(name2, glmExtractRotation(avatarTargetMat2), extractTranslation(avatarTargetMat2), WHITE); - } + glm::mat4 geomTargetMat2 = createMatFromQuatAndPos(midTarget.getRotation(), midTarget.getTranslation()); + glm::mat4 avatarTargetMat2 = rigToAvatarMat * context.getGeometryToRigMatrix() * geomTargetMat2; + QString name2 = QString("ikTargetSplineMid"); + DebugDraw::getInstance().addMyAvatarMarker(name2, glmExtractRotation(avatarTargetMat2), extractTranslation(avatarTargetMat2), WHITE); glm::mat4 geomTargetMat3 = createMatFromQuatAndPos(baseTargetAbsolutePose.rot(), baseTargetAbsolutePose.trans()); glm::mat4 avatarTargetMat3 = rigToAvatarMat * context.getGeometryToRigMatrix() * geomTargetMat3; @@ -370,9 +367,9 @@ void AnimSplineIK::solveTargetWithSpline(const AnimContext& context, int base, c // interp based on ratio of the joint. if (splineJointInfo.ratio < 1.0f) { float flexInterp = splineJointInfo.ratio * (float)(numFlexCoeff - 1); - int startCoeff = floor(flexInterp); + int startCoeff = (int)glm::floor(flexInterp); float partial = flexInterp - startCoeff; - interpedCoefficient = target.getFlexCoefficient(startCoeff) * (1 - partial) + target.getFlexCoefficient(startCoeff + 1) * partial; + interpedCoefficient = target.getFlexCoefficient(startCoeff) * (1.0f - partial) + target.getFlexCoefficient(startCoeff + 1) * partial; } else { interpedCoefficient = target.getFlexCoefficient(numFlexCoeff - 1); } @@ -404,7 +401,7 @@ void AnimSplineIK::solveTargetWithSpline(const AnimContext& context, int base, c } if (!chainInfoOut.setRelativePoseAtJointIndex(splineJointInfo.jointIndex, relPose)) { - qCDebug(animation) << "we didn't find the joint index for the spline!!!!"; + qCDebug(animation) << "error: joint not found in spline chain"; } parentAbsPose = flexedAbsPose; diff --git a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp index bc2cb8a0ba..1552ef607f 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp +++ b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp @@ -1850,15 +1850,13 @@ void Avatar::buildSpine2SplineRatioCache() { _spine2SplineRatio = glm::dot(baseToSpine2, baseToTipNormal) / baseToTipLength; CubicHermiteSplineFunctorWithArcLength defaultSpline = computeSplineFromTipAndBase(headRigDefaultPose, hipsRigDefaultPose); - //CubicHermiteSplineFunctorWithArcLength defaultSpline(headRigDefaultPose, hipsRigDefaultPose); + // measure the total arc length along the spline float totalDefaultArcLength = defaultSpline.arcLength(1.0f); float t = defaultSpline.arcLengthInverse(_spine2SplineRatio * totalDefaultArcLength); glm::vec3 defaultSplineSpine2Translation = defaultSpline(t); _spine2SplineOffset = spine2Position - defaultSplineSpine2Translation; - - qCDebug(avatars_renderer) << "the avatar spline numbers are " << _spine2SplineRatio << " and " << _spine2SplineOffset; } } diff --git a/libraries/avatars-renderer/src/avatars-renderer/Avatar.h b/libraries/avatars-renderer/src/avatars-renderer/Avatar.h index acfcdc4ee4..bc8df0ebe1 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/Avatar.h +++ b/libraries/avatars-renderer/src/avatars-renderer/Avatar.h @@ -558,7 +558,6 @@ protected: float getHeadHeight() const; float getPelvisFloatingHeight() const; glm::vec3 getDisplayNamePosition() const; - Transform calculateDisplayNameTransform(const ViewFrustum& view, const glm::vec3& textPosition) const; void renderDisplayName(gpu::Batch& batch, const ViewFrustum& view, const glm::vec3& textPosition) const; From d547d5b854af84dcab4ff2311d646f2eaf47a895 Mon Sep 17 00:00:00 2001 From: amantley Date: Wed, 30 Jan 2019 18:15:47 -0800 Subject: [PATCH 037/112] changed the json reader to take an array not a string for the flex targets --- .../avatar-animation_withSplineIKNode.json | 4 ++-- libraries/animation/src/AnimNodeLoader.cpp | 24 +++++++++++++++++-- libraries/animation/src/AnimSplineIK.cpp | 21 ++++++++-------- libraries/animation/src/AnimSplineIK.h | 4 ++-- 4 files changed, 36 insertions(+), 17 deletions(-) diff --git a/interface/resources/avatar/avatar-animation_withSplineIKNode.json b/interface/resources/avatar/avatar-animation_withSplineIKNode.json index a6283f0771..fa67b6b24b 100644 --- a/interface/resources/avatar/avatar-animation_withSplineIKNode.json +++ b/interface/resources/avatar/avatar-animation_withSplineIKNode.json @@ -192,8 +192,8 @@ "tipRotationVar": "headRotation", "alphaVar": "splineIKAlpha", "enabledVar": "splineIKEnabled", - "tipTargetFlexCoefficients": "1.0, 1.0, 1.0, 1.0, 1.0", - "midTargetFlexCoefficients": "1.0, 1.0, 1.0" + "tipTargetFlexCoefficients": [ 1.0, 1.0, 1.0, 1.0, 1.0 ], + "midTargetFlexCoefficients": [ 1.0, 1.0, 1.0 ] }, "children": [ { diff --git a/libraries/animation/src/AnimNodeLoader.cpp b/libraries/animation/src/AnimNodeLoader.cpp index 62e848872b..b637d131f8 100644 --- a/libraries/animation/src/AnimNodeLoader.cpp +++ b/libraries/animation/src/AnimNodeLoader.cpp @@ -594,8 +594,28 @@ static AnimNode::Pointer loadSplineIKNode(const QJsonObject& jsonObj, const QStr READ_STRING(tipRotationVar, jsonObj, id, jsonUrl, nullptr); READ_STRING(alphaVar, jsonObj, id, jsonUrl, nullptr); READ_STRING(enabledVar, jsonObj, id, jsonUrl, nullptr); - READ_STRING(tipTargetFlexCoefficients, jsonObj, id, jsonUrl, nullptr); - READ_STRING(midTargetFlexCoefficients, jsonObj, id, jsonUrl, nullptr); + + auto tipFlexCoefficientsValue = jsonObj.value("tipTargetFlexCoefficients"); + if (!tipFlexCoefficientsValue.isArray()) { + qCCritical(animation) << "AnimNodeLoader, bad or missing tip flex array"; + return nullptr; + } + auto tipFlexCoefficientsArray = tipFlexCoefficientsValue.toArray(); + std::vector tipTargetFlexCoefficients; + for (const auto& value : tipFlexCoefficientsArray) { + tipTargetFlexCoefficients.push_back((float)value.toDouble()); + } + + auto midFlexCoefficientsValue = jsonObj.value("midTargetFlexCoefficients"); + if (!midFlexCoefficientsValue.isArray()) { + qCCritical(animation) << "AnimNodeLoader, bad or missing mid flex array"; + return nullptr; + } + auto midFlexCoefficientsArray = midFlexCoefficientsValue.toArray(); + std::vector midTargetFlexCoefficients; + for (const auto& midValue : midFlexCoefficientsArray) { + midTargetFlexCoefficients.push_back((float)midValue.toDouble()); + } auto node = std::make_shared(id, alpha, enabled, interpDuration, baseJointName, midJointName, tipJointName, diff --git a/libraries/animation/src/AnimSplineIK.cpp b/libraries/animation/src/AnimSplineIK.cpp index e204a8f2d6..8b44ef4478 100644 --- a/libraries/animation/src/AnimSplineIK.cpp +++ b/libraries/animation/src/AnimSplineIK.cpp @@ -29,8 +29,8 @@ AnimSplineIK::AnimSplineIK(const QString& id, float alpha, bool enabled, float i const QString& tipRotationVar, const QString& alphaVar, const QString& enabledVar, - const QString& tipTargetFlexCoefficients, - const QString& midTargetFlexCoefficients) : + const std::vector tipTargetFlexCoefficients, + const std::vector midTargetFlexCoefficients) : AnimNode(AnimNode::Type::SplineIK, id), _alpha(alpha), _enabled(enabled), @@ -48,21 +48,20 @@ AnimSplineIK::AnimSplineIK(const QString& id, float alpha, bool enabled, float i _enabledVar(enabledVar) { - QStringList tipTargetFlexCoefficientsValues = tipTargetFlexCoefficients.split(',', QString::SkipEmptyParts); - for (int i = 0; i < tipTargetFlexCoefficientsValues.size(); i++) { + for (int i = 0; i < tipTargetFlexCoefficients.size(); i++) { if (i < MAX_NUMBER_FLEX_VARIABLES) { - _tipTargetFlexCoefficients[i] = (float)tipTargetFlexCoefficientsValues[i].toDouble(); + _tipTargetFlexCoefficients[i] = tipTargetFlexCoefficients[i]; } - } - _numTipTargetFlexCoefficients = std::min(tipTargetFlexCoefficientsValues.size(), MAX_NUMBER_FLEX_VARIABLES); + + } + _numTipTargetFlexCoefficients = std::min((int)tipTargetFlexCoefficients.size(), MAX_NUMBER_FLEX_VARIABLES); - QStringList midTargetFlexCoefficientsValues = midTargetFlexCoefficients.split(',', QString::SkipEmptyParts); - for (int i = 0; i < midTargetFlexCoefficientsValues.size(); i++) { + for (int i = 0; i < midTargetFlexCoefficients.size(); i++) { if (i < MAX_NUMBER_FLEX_VARIABLES) { - _midTargetFlexCoefficients[i] = (float)midTargetFlexCoefficientsValues[i].toDouble(); + _midTargetFlexCoefficients[i] = midTargetFlexCoefficients[i]; } } - _numMidTargetFlexCoefficients = std::min(midTargetFlexCoefficientsValues.size(), MAX_NUMBER_FLEX_VARIABLES); + _numMidTargetFlexCoefficients = std::min((int)midTargetFlexCoefficients.size(), MAX_NUMBER_FLEX_VARIABLES); } diff --git a/libraries/animation/src/AnimSplineIK.h b/libraries/animation/src/AnimSplineIK.h index ee3f29d6df..6a07ec5565 100644 --- a/libraries/animation/src/AnimSplineIK.h +++ b/libraries/animation/src/AnimSplineIK.h @@ -24,8 +24,8 @@ public: const QString& midPositionVar, const QString& midRotationVar, const QString& tipPositionVar, const QString& tipRotationVar, const QString& alphaVar, const QString& enabledVar, - const QString& tipTargetFlexCoefficients, - const QString& midTargetFlexCoefficients); + const std::vector tipTargetFlexCoefficients, + const std::vector midTargetFlexCoefficients); virtual ~AnimSplineIK() override; virtual const AnimPoseVec& evaluate(const AnimVariantMap& animVars, const AnimContext& context, float dt, AnimVariantMap& triggersOut) override; From ffd374e7d477358a4e445cd323a942e9345ca89d Mon Sep 17 00:00:00 2001 From: amantley Date: Thu, 31 Jan 2019 10:05:08 -0800 Subject: [PATCH 038/112] whitespace --- interface/src/avatar/MySkeletonModel.cpp | 2 +- libraries/animation/src/AnimSplineIK.cpp | 14 +++++--------- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/interface/src/avatar/MySkeletonModel.cpp b/interface/src/avatar/MySkeletonModel.cpp index f4cfb79314..73021fb3f4 100755 --- a/interface/src/avatar/MySkeletonModel.cpp +++ b/interface/src/avatar/MySkeletonModel.cpp @@ -44,7 +44,7 @@ static CubicHermiteSplineFunctorWithArcLength computeSplineFromTipAndBase(const } static glm::vec3 computeSpine2WithHeadHipsSpline(MyAvatar* myAvatar, AnimPose hipsIKTargetPose, AnimPose headIKTargetPose) { - + // the the ik targets to compute the spline with CubicHermiteSplineFunctorWithArcLength splineFinal = computeSplineFromTipAndBase(headIKTargetPose, hipsIKTargetPose); diff --git a/libraries/animation/src/AnimSplineIK.cpp b/libraries/animation/src/AnimSplineIK.cpp index 8b44ef4478..a12d6fbd0d 100644 --- a/libraries/animation/src/AnimSplineIK.cpp +++ b/libraries/animation/src/AnimSplineIK.cpp @@ -52,7 +52,6 @@ AnimSplineIK::AnimSplineIK(const QString& id, float alpha, bool enabled, float i if (i < MAX_NUMBER_FLEX_VARIABLES) { _tipTargetFlexCoefficients[i] = tipTargetFlexCoefficients[i]; } - } _numTipTargetFlexCoefficients = std::min((int)tipTargetFlexCoefficients.size(), MAX_NUMBER_FLEX_VARIABLES); @@ -70,7 +69,6 @@ AnimSplineIK::~AnimSplineIK() { } const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const AnimContext& context, float dt, AnimVariantMap& triggersOut) { - assert(_children.size() == 1); if (_children.size() != 1) { return _poses; @@ -135,8 +133,6 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const _poses[_baseJointIndex] = baseParentAbsPose.inverse() * baseTargetAbsolutePose; _poses[_baseJointIndex].scale() = glm::vec3(1.0f); - - // initialize the middle joint target IKTarget midTarget; midTarget.setType((int)IKTarget::Type::Spline); @@ -167,7 +163,7 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const tipTarget.setPose(tipRotation, tipTranslation); tipTarget.setWeight(1.0f); tipTarget.setFlexCoefficients(_numTipTargetFlexCoefficients, _tipTargetFlexCoefficients); - + // solve the upper spine spline AnimChain upperJointChain; AnimPoseVec finalAbsolutePoses; @@ -241,7 +237,7 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const } else if (context.getEnableDebugDrawIKTargets() != _previousEnableDebugIKTargets) { - + // remove markers if they were added last frame. QString name = QString("ikTargetSplineTip"); DebugDraw::getInstance().removeMyAvatarMarker(name); @@ -374,9 +370,9 @@ void AnimSplineIK::solveTargetWithSpline(const AnimContext& context, int base, c } } ::blend(1, &absolutePoses[splineJointInfo.jointIndex], &desiredAbsPose, interpedCoefficient, &flexedAbsPose); - + AnimPose relPose = parentAbsPose.inverse() * flexedAbsPose; - + bool constrained = false; if (splineJointInfo.jointIndex != base) { // constrain the amount the spine can stretch or compress @@ -398,7 +394,7 @@ void AnimSplineIK::solveTargetWithSpline(const AnimContext& context, int base, c relPose.trans() = glm::vec3(0.0f); } } - + if (!chainInfoOut.setRelativePoseAtJointIndex(splineJointInfo.jointIndex, relPose)) { qCDebug(animation) << "error: joint not found in spline chain"; } From 61b019d1763724c30bb75e8a98e429d8df7fc9de Mon Sep 17 00:00:00 2001 From: amantley Date: Thu, 31 Jan 2019 14:13:35 -0800 Subject: [PATCH 039/112] added new constructor for cubichermitespline that takes quat and vec3. this means we don't need computeSplineFromTipAndBase to be declared in multiple files --- interface/src/avatar/MySkeletonModel.cpp | 12 +---------- libraries/animation/src/AnimSplineIK.cpp | 18 ++++------------ libraries/animation/src/IKTarget.h | 2 +- .../src/avatars-renderer/Avatar.cpp | 12 +---------- libraries/shared/src/CubicHermiteSpline.h | 21 +++++++++++++++++++ 5 files changed, 28 insertions(+), 37 deletions(-) diff --git a/interface/src/avatar/MySkeletonModel.cpp b/interface/src/avatar/MySkeletonModel.cpp index 73021fb3f4..953b8a4c73 100755 --- a/interface/src/avatar/MySkeletonModel.cpp +++ b/interface/src/avatar/MySkeletonModel.cpp @@ -33,20 +33,10 @@ Rig::CharacterControllerState convertCharacterControllerState(CharacterControlle }; } -static CubicHermiteSplineFunctorWithArcLength computeSplineFromTipAndBase(const AnimPose& tipPose, const AnimPose& basePose, float baseGain = 1.0f, float tipGain = 1.0f) { - float linearDistance = glm::length(basePose.trans() - tipPose.trans()); - glm::vec3 p0 = basePose.trans(); - glm::vec3 m0 = baseGain * linearDistance * (basePose.rot() * Vectors::UNIT_Y); - glm::vec3 p1 = tipPose.trans(); - glm::vec3 m1 = tipGain * linearDistance * (tipPose.rot() * Vectors::UNIT_Y); - - return CubicHermiteSplineFunctorWithArcLength(p0, m0, p1, m1); -} - static glm::vec3 computeSpine2WithHeadHipsSpline(MyAvatar* myAvatar, AnimPose hipsIKTargetPose, AnimPose headIKTargetPose) { // the the ik targets to compute the spline with - CubicHermiteSplineFunctorWithArcLength splineFinal = computeSplineFromTipAndBase(headIKTargetPose, hipsIKTargetPose); + CubicHermiteSplineFunctorWithArcLength splineFinal(headIKTargetPose.rot(), headIKTargetPose.trans(), hipsIKTargetPose.rot(), hipsIKTargetPose.trans()); // measure the total arc length along the spline float totalArcLength = splineFinal.arcLength(1.0f); diff --git a/libraries/animation/src/AnimSplineIK.cpp b/libraries/animation/src/AnimSplineIK.cpp index a12d6fbd0d..4dab904c05 100644 --- a/libraries/animation/src/AnimSplineIK.cpp +++ b/libraries/animation/src/AnimSplineIK.cpp @@ -287,16 +287,6 @@ void AnimSplineIK::setSkeletonInternal(AnimSkeleton::ConstPointer skeleton) { lookUpIndices(); } -static CubicHermiteSplineFunctorWithArcLength computeSplineFromTipAndBase(const AnimPose& tipPose, const AnimPose& basePose, float baseGain = 1.0f, float tipGain = 1.0f) { - float linearDistance = glm::length(basePose.trans() - tipPose.trans()); - glm::vec3 p0 = basePose.trans(); - glm::vec3 m0 = baseGain * linearDistance * (basePose.rot() * Vectors::UNIT_Y); - glm::vec3 p1 = tipPose.trans(); - glm::vec3 m1 = tipGain * linearDistance * (tipPose.rot() * Vectors::UNIT_Y); - - return CubicHermiteSplineFunctorWithArcLength(p0, m0, p1, m1); -} - void AnimSplineIK::solveTargetWithSpline(const AnimContext& context, int base, const IKTarget& target, const AnimPoseVec& absolutePoses, bool debug, AnimChain& chainInfoOut) const { // build spline from tip to base @@ -308,9 +298,9 @@ void AnimSplineIK::solveTargetWithSpline(const AnimContext& context, int base, c // set gain factors so that more curvature occurs near the tip of the spline. const float HIPS_GAIN = 0.5f; const float HEAD_GAIN = 1.0f; - spline = computeSplineFromTipAndBase(tipPose, basePose, HIPS_GAIN, HEAD_GAIN); + spline = CubicHermiteSplineFunctorWithArcLength(tipPose.rot(), tipPose.trans(), basePose.rot(), basePose.trans(), HIPS_GAIN, HEAD_GAIN); } else { - spline = computeSplineFromTipAndBase(tipPose, basePose); + spline = CubicHermiteSplineFunctorWithArcLength(tipPose.rot(),tipPose.trans(), basePose.rot(), basePose.trans()); } float totalArcLength = spline.arcLength(1.0f); @@ -437,9 +427,9 @@ void AnimSplineIK::computeAndCacheSplineJointInfosForIKTarget(const AnimContext& // set gain factors so that more curvature occurs near the tip of the spline. const float HIPS_GAIN = 0.5f; const float HEAD_GAIN = 1.0f; - spline = computeSplineFromTipAndBase(tipPose, basePose, HIPS_GAIN, HEAD_GAIN); + spline = CubicHermiteSplineFunctorWithArcLength(tipPose.rot(), tipPose.trans(), basePose.rot(), basePose.trans(), HIPS_GAIN, HEAD_GAIN); } else { - spline = computeSplineFromTipAndBase(tipPose, basePose); + spline = CubicHermiteSplineFunctorWithArcLength(tipPose.rot(), tipPose.trans(), basePose.rot(), basePose.trans()); } // measure the total arc length along the spline float totalArcLength = spline.arcLength(1.0f); diff --git a/libraries/animation/src/IKTarget.h b/libraries/animation/src/IKTarget.h index 5c77b3c29a..57eaff9c30 100644 --- a/libraries/animation/src/IKTarget.h +++ b/libraries/animation/src/IKTarget.h @@ -35,7 +35,7 @@ public: bool getPoleVectorEnabled() const { return _poleVectorEnabled; } int getIndex() const { return _index; } Type getType() const { return _type; } - int getNumFlexCoefficients() const { return _numFlexCoefficients; } + int getNumFlexCoefficients() const { return (int)_numFlexCoefficients; } float getFlexCoefficient(size_t chainDepth) const; void setPose(const glm::quat& rotation, const glm::vec3& translation); diff --git a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp index b77657dc29..ca5a61b3d6 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp +++ b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp @@ -1962,16 +1962,6 @@ void Avatar::buildUnscaledEyeHeightCache() { } } -static CubicHermiteSplineFunctorWithArcLength computeSplineFromTipAndBase(const AnimPose& tipPose, const AnimPose& basePose, float baseGain = 1.0f, float tipGain = 1.0f) { - float linearDistance = glm::length(basePose.trans() - tipPose.trans()); - glm::vec3 p0 = basePose.trans(); - glm::vec3 m0 = baseGain * linearDistance * (basePose.rot() * Vectors::UNIT_Y); - glm::vec3 p1 = tipPose.trans(); - glm::vec3 m1 = tipGain * linearDistance * (tipPose.rot() * Vectors::UNIT_Y); - - return CubicHermiteSplineFunctorWithArcLength(p0, m0, p1, m1); -} - void Avatar::buildSpine2SplineRatioCache() { if (_skeletonModel) { auto& rig = _skeletonModel->getRig(); @@ -1988,7 +1978,7 @@ void Avatar::buildSpine2SplineRatioCache() { _spine2SplineRatio = glm::dot(baseToSpine2, baseToTipNormal) / baseToTipLength; - CubicHermiteSplineFunctorWithArcLength defaultSpline = computeSplineFromTipAndBase(headRigDefaultPose, hipsRigDefaultPose); + CubicHermiteSplineFunctorWithArcLength defaultSpline(headRigDefaultPose.rot(), headRigDefaultPose.trans(), hipsRigDefaultPose.rot(), hipsRigDefaultPose.trans()); // measure the total arc length along the spline float totalDefaultArcLength = defaultSpline.arcLength(1.0f); diff --git a/libraries/shared/src/CubicHermiteSpline.h b/libraries/shared/src/CubicHermiteSpline.h index da2ed26de4..65fbcb75ed 100644 --- a/libraries/shared/src/CubicHermiteSpline.h +++ b/libraries/shared/src/CubicHermiteSpline.h @@ -79,6 +79,27 @@ public: } } + CubicHermiteSplineFunctorWithArcLength(const glm::quat& tipRot, const glm::vec3& tipTrans, const glm::quat& baseRot, const glm::vec3& baseTrans, float baseGain = 1.0f, float tipGain = 1.0f) : CubicHermiteSplineFunctor() { + + float linearDistance = glm::length(baseTrans - tipTrans); + _p0 = baseTrans; + _m0 = baseGain * linearDistance * (baseRot * Vectors::UNIT_Y); + _p1 = tipTrans; + _m1 = tipGain * linearDistance * (tipRot * Vectors::UNIT_Y); + + // initialize _values with the accumulated arcLength along the spline. + const float DELTA = 1.0f / NUM_SUBDIVISIONS; + float alpha = 0.0f; + float accum = 0.0f; + _values[0] = 0.0f; + for (int i = 1; i < NUM_SUBDIVISIONS + 1; i++) { + accum += glm::distance(this->operator()(alpha), + this->operator()(alpha + DELTA)); + alpha += DELTA; + _values[i] = accum; + } + } + CubicHermiteSplineFunctorWithArcLength(const CubicHermiteSplineFunctorWithArcLength& orig) : CubicHermiteSplineFunctor(orig) { memcpy(_values, orig._values, sizeof(float) * (NUM_SUBDIVISIONS + 1)); } From 25c5a2f41a6395646d2444fcc822cad626680400 Mon Sep 17 00:00:00 2001 From: amantley Date: Thu, 31 Jan 2019 17:23:56 -0800 Subject: [PATCH 040/112] fixed mac/linux build error --- libraries/animation/src/AnimSplineIK.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/animation/src/AnimSplineIK.h b/libraries/animation/src/AnimSplineIK.h index 6a07ec5565..9fefb32276 100644 --- a/libraries/animation/src/AnimSplineIK.h +++ b/libraries/animation/src/AnimSplineIK.h @@ -90,7 +90,7 @@ protected: AnimPose offsetPose; // local offset from the spline to the joint. }; - void AnimSplineIK::solveTargetWithSpline(const AnimContext& context, int base, const IKTarget& target, const AnimPoseVec& absolutePoses, bool debug, AnimChain& chainInfoOut) const; + void solveTargetWithSpline(const AnimContext& context, int base, const IKTarget& target, const AnimPoseVec& absolutePoses, bool debug, AnimChain& chainInfoOut) const; void computeAndCacheSplineJointInfosForIKTarget(const AnimContext& context, int base, const IKTarget& target) const; const std::vector* findOrCreateSplineJointInfo(const AnimContext& context, int base, const IKTarget& target) const; mutable std::map> _splineJointInfoMap; From dd99f93d1ac9a703e7f864df72eff634dd323336 Mon Sep 17 00:00:00 2001 From: Angus Antley Date: Thu, 31 Jan 2019 19:52:17 -0800 Subject: [PATCH 041/112] fixed missplaced static const --- libraries/animation/src/AnimSplineIK.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libraries/animation/src/AnimSplineIK.h b/libraries/animation/src/AnimSplineIK.h index 9fefb32276..bca0f7fe77 100644 --- a/libraries/animation/src/AnimSplineIK.h +++ b/libraries/animation/src/AnimSplineIK.h @@ -15,6 +15,8 @@ #include "IKTarget.h" #include "AnimChain.h" +static const int MAX_NUMBER_FLEX_VARIABLES = 10; + // Spline IK for the spine class AnimSplineIK : public AnimNode { public: @@ -66,7 +68,6 @@ protected: QString _alphaVar; // float - (0, 1) 0 means underPoses only, 1 means IK only. QString _enabledVar; - static const int MAX_NUMBER_FLEX_VARIABLES = 10; float _tipTargetFlexCoefficients[MAX_NUMBER_FLEX_VARIABLES]; float _midTargetFlexCoefficients[MAX_NUMBER_FLEX_VARIABLES]; int _numTipTargetFlexCoefficients { 0 }; From a2ef7edf104b6556b3a68cd0c4d6c2bc6d2c0f3f Mon Sep 17 00:00:00 2001 From: Angus Antley Date: Thu, 31 Jan 2019 20:43:13 -0800 Subject: [PATCH 042/112] cleaned up some warnings --- libraries/animation/src/AnimSplineIK.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries/animation/src/AnimSplineIK.cpp b/libraries/animation/src/AnimSplineIK.cpp index 4dab904c05..d1f7bf8b3a 100644 --- a/libraries/animation/src/AnimSplineIK.cpp +++ b/libraries/animation/src/AnimSplineIK.cpp @@ -48,14 +48,14 @@ AnimSplineIK::AnimSplineIK(const QString& id, float alpha, bool enabled, float i _enabledVar(enabledVar) { - for (int i = 0; i < tipTargetFlexCoefficients.size(); i++) { + for (int i = 0; i < (int)tipTargetFlexCoefficients.size(); i++) { if (i < MAX_NUMBER_FLEX_VARIABLES) { _tipTargetFlexCoefficients[i] = tipTargetFlexCoefficients[i]; } } _numTipTargetFlexCoefficients = std::min((int)tipTargetFlexCoefficients.size(), MAX_NUMBER_FLEX_VARIABLES); - for (int i = 0; i < midTargetFlexCoefficients.size(); i++) { + for (int i = 0; i < (int)midTargetFlexCoefficients.size(); i++) { if (i < MAX_NUMBER_FLEX_VARIABLES) { _midTargetFlexCoefficients[i] = midTargetFlexCoefficients[i]; } @@ -345,7 +345,7 @@ void AnimSplineIK::solveTargetWithSpline(const AnimContext& context, int base, c // get the number of flex coeff for this spline float interpedCoefficient = 1.0f; int numFlexCoeff = target.getNumFlexCoefficients(); - if (numFlexCoeff == splineJointInfoVec->size()) { + if (numFlexCoeff == (int)splineJointInfoVec->size()) { // then do nothing special interpedCoefficient = target.getFlexCoefficient(i); } else { From 34d32eeda87c3613622c06c48d85038ca5ef9fdf Mon Sep 17 00:00:00 2001 From: amantley Date: Mon, 4 Feb 2019 10:17:22 -0800 Subject: [PATCH 043/112] removed the extra ikoverlay in the avatar-animation.json --- .../avatar-animation_withSplineIKNode.json | 3434 ++++++++--------- 1 file changed, 1708 insertions(+), 1726 deletions(-) diff --git a/interface/resources/avatar/avatar-animation_withSplineIKNode.json b/interface/resources/avatar/avatar-animation_withSplineIKNode.json index fa67b6b24b..b1f198c52c 100644 --- a/interface/resources/avatar/avatar-animation_withSplineIKNode.json +++ b/interface/resources/avatar/avatar-animation_withSplineIKNode.json @@ -197,12 +197,13 @@ }, "children": [ { - "id": "ikOverlay", + "id": "defaultPoseOverlay", "type": "overlay", "data": { "alpha": 0.0, - "alphaVar": "ikOverlayAlpha", - "boneSet": "fullBody" + "alphaVar": "defaultPoseOverlayAlpha", + "boneSet": "fullBody", + "boneSetVar": "defaultPoseOverlayBoneSet" }, "children": [ { @@ -213,110 +214,325 @@ "children": [] }, { - "id": "defaultPoseOverlay", + "id": "rightHandOverlay", "type": "overlay", "data": { "alpha": 0.0, - "alphaVar": "defaultPoseOverlayAlpha", - "boneSet": "fullBody", - "boneSetVar": "defaultPoseOverlayBoneSet" + "boneSet": "rightHand", + "alphaVar": "rightHandOverlayAlpha" }, "children": [ { - "id": "defaultPose", - "type": "defaultPose", + "id": "rightHandStateMachine", + "type": "stateMachine", "data": { - }, - "children": [] - }, - { - "id": "rightHandOverlay", - "type": "overlay", - "data": { - "alpha": 0.0, - "boneSet": "rightHand", - "alphaVar": "rightHandOverlayAlpha" + "currentState": "rightHandGrasp", + "states": [ + { + "id": "rightHandGrasp", + "interpTarget": 3, + "interpDuration": 3, + "transitions": [ + { + "var": "isRightIndexPoint", + "state": "rightIndexPoint" + }, + { + "var": "isRightThumbRaise", + "state": "rightThumbRaise" + }, + { + "var": "isRightIndexPointAndThumbRaise", + "state": "rightIndexPointAndThumbRaise" + } + ] + }, + { + "id": "rightIndexPoint", + "interpTarget": 15, + "interpDuration": 3, + "transitions": [ + { + "var": "isRightHandGrasp", + "state": "rightHandGrasp" + }, + { + "var": "isRightThumbRaise", + "state": "rightThumbRaise" + }, + { + "var": "isRightIndexPointAndThumbRaise", + "state": "rightIndexPointAndThumbRaise" + } + ] + }, + { + "id": "rightThumbRaise", + "interpTarget": 15, + "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" + } + ] + } + ] }, "children": [ { - "id": "rightHandStateMachine", + "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", "type": "stateMachine", "data": { - "currentState": "rightHandGrasp", + "currentState": "leftHandGrasp", "states": [ { - "id": "rightHandGrasp", + "id": "leftHandGrasp", "interpTarget": 3, "interpDuration": 3, "transitions": [ { - "var": "isRightIndexPoint", - "state": "rightIndexPoint" + "var": "isLeftIndexPoint", + "state": "leftIndexPoint" }, { - "var": "isRightThumbRaise", - "state": "rightThumbRaise" + "var": "isLeftThumbRaise", + "state": "leftThumbRaise" }, { - "var": "isRightIndexPointAndThumbRaise", - "state": "rightIndexPointAndThumbRaise" + "var": "isLeftIndexPointAndThumbRaise", + "state": "leftIndexPointAndThumbRaise" } ] }, { - "id": "rightIndexPoint", + "id": "leftIndexPoint", "interpTarget": 15, "interpDuration": 3, "transitions": [ { - "var": "isRightHandGrasp", - "state": "rightHandGrasp" + "var": "isLeftHandGrasp", + "state": "leftHandGrasp" }, { - "var": "isRightThumbRaise", - "state": "rightThumbRaise" + "var": "isLeftThumbRaise", + "state": "leftThumbRaise" }, { - "var": "isRightIndexPointAndThumbRaise", - "state": "rightIndexPointAndThumbRaise" + "var": "isLeftIndexPointAndThumbRaise", + "state": "leftIndexPointAndThumbRaise" } ] }, { - "id": "rightThumbRaise", + "id": "leftThumbRaise", "interpTarget": 15, "interpDuration": 3, "transitions": [ { - "var": "isRightHandGrasp", - "state": "rightHandGrasp" + "var": "isLeftHandGrasp", + "state": "leftHandGrasp" }, { - "var": "isRightIndexPoint", - "state": "rightIndexPoint" + "var": "isLeftIndexPoint", + "state": "leftIndexPoint" }, { - "var": "isRightIndexPointAndThumbRaise", - "state": "rightIndexPointAndThumbRaise" + "var": "isLeftIndexPointAndThumbRaise", + "state": "leftIndexPointAndThumbRaise" } ] }, { - "id": "rightIndexPointAndThumbRaise", + "id": "leftIndexPointAndThumbRaise", "interpTarget": 15, "interpDuration": 3, "transitions": [ { - "var": "isRightHandGrasp", - "state": "rightHandGrasp" + "var": "isLeftHandGrasp", + "state": "leftHandGrasp" }, { - "var": "isRightIndexPoint", - "state": "rightIndexPoint" + "var": "isLeftIndexPoint", + "state": "leftIndexPoint" }, { - "var": "isRightThumbRaise", - "state": "rightThumbRaise" + "var": "isLeftThumbRaise", + "state": "leftThumbRaise" } ] } @@ -324,18 +540,18 @@ }, "children": [ { - "id": "rightHandGrasp", + "id": "leftHandGrasp", "type": "blendLinear", "data": { "alpha": 0.0, - "alphaVar": "rightHandGraspAlpha" + "alphaVar": "leftHandGraspAlpha" }, "children": [ { - "id": "rightHandGraspOpen", + "id": "leftHandGraspOpen", "type": "clip", "data": { - "url": "qrc:///avatar/animations/hydra_pose_open_right.fbx", + "url": "qrc:///avatar/animations/hydra_pose_open_left.fbx", "startFrame": 0.0, "endFrame": 0.0, "timeScale": 1.0, @@ -344,12 +560,12 @@ "children": [] }, { - "id": "rightHandGraspClosed", + "id": "leftHandGraspClosed", "type": "clip", "data": { - "url": "qrc:///avatar/animations/hydra_pose_closed_right.fbx", - "startFrame": 0.0, - "endFrame": 0.0, + "url": "qrc:///avatar/animations/hydra_pose_closed_left.fbx", + "startFrame": 10.0, + "endFrame": 10.0, "timeScale": 1.0, "loopFlag": true }, @@ -358,18 +574,18 @@ ] }, { - "id": "rightIndexPoint", + "id": "leftIndexPoint", "type": "blendLinear", "data": { "alpha": 0.0, - "alphaVar": "rightHandGraspAlpha" + "alphaVar": "leftHandGraspAlpha" }, "children": [ { - "id": "rightIndexPointOpen", + "id": "leftIndexPointOpen", "type": "clip", "data": { - "url": "qrc:///avatar/animations/touch_point_open_right.fbx", + "url": "qrc:///avatar/animations/touch_point_open_left.fbx", "startFrame": 15.0, "endFrame": 15.0, "timeScale": 1.0, @@ -378,10 +594,10 @@ "children": [] }, { - "id": "rightIndexPointClosed", + "id": "leftIndexPointClosed", "type": "clip", "data": { - "url": "qrc:///avatar/animations/touch_point_closed_right.fbx", + "url": "qrc:///avatar/animations/touch_point_closed_left.fbx", "startFrame": 15.0, "endFrame": 15.0, "timeScale": 1.0, @@ -392,18 +608,18 @@ ] }, { - "id": "rightThumbRaise", + "id": "leftThumbRaise", "type": "blendLinear", "data": { "alpha": 0.0, - "alphaVar": "rightHandGraspAlpha" + "alphaVar": "leftHandGraspAlpha" }, "children": [ { - "id": "rightThumbRaiseOpen", + "id": "leftThumbRaiseOpen", "type": "clip", "data": { - "url": "qrc:///avatar/animations/touch_thumb_open_right.fbx", + "url": "qrc:///avatar/animations/touch_thumb_open_left.fbx", "startFrame": 15.0, "endFrame": 15.0, "timeScale": 1.0, @@ -412,10 +628,10 @@ "children": [] }, { - "id": "rightThumbRaiseClosed", + "id": "leftThumbRaiseClosed", "type": "clip", "data": { - "url": "qrc:///avatar/animations/touch_thumb_closed_right.fbx", + "url": "qrc:///avatar/animations/touch_thumb_closed_left.fbx", "startFrame": 15.0, "endFrame": 15.0, "timeScale": 1.0, @@ -426,18 +642,18 @@ ] }, { - "id": "rightIndexPointAndThumbRaise", + "id": "leftIndexPointAndThumbRaise", "type": "blendLinear", "data": { "alpha": 0.0, - "alphaVar": "rightHandGraspAlpha" + "alphaVar": "leftHandGraspAlpha" }, "children": [ { - "id": "rightIndexPointAndThumbRaiseOpen", + "id": "leftIndexPointAndThumbRaiseOpen", "type": "clip", "data": { - "url": "qrc:///avatar/animations/touch_thumb_point_open_right.fbx", + "url": "qrc:///avatar/animations/touch_thumb_point_open_left.fbx", "startFrame": 15.0, "endFrame": 15.0, "timeScale": 1.0, @@ -446,10 +662,10 @@ "children": [] }, { - "id": "rightIndexPointAndThumbRaiseClosed", + "id": "leftIndexPointAndThumbRaiseClosed", "type": "clip", "data": { - "url": "qrc:///avatar/animations/touch_thumb_point_closed_right.fbx", + "url": "qrc:///avatar/animations/touch_thumb_point_closed_left.fbx", "startFrame": 15.0, "endFrame": 15.0, "timeScale": 1.0, @@ -462,93 +678,871 @@ ] }, { - "id": "leftHandOverlay", - "type": "overlay", + "id": "mainStateMachine", + "type": "stateMachine", "data": { - "alpha": 0.0, - "boneSet": "leftHand", - "alphaVar": "leftHandOverlayAlpha" + "outputJoints": [ "LeftFoot", "RightFoot" ], + "currentState": "idle", + "states": [ + { + "id": "idle", + "interpTarget": 20, + "interpDuration": 8, + "interpType": "snapshotPrev", + "transitions": [ + { + "var": "isMovingForward", + "state": "WALKFWD" + }, + { + "var": "isMovingBackward", + "state": "WALKBWD" + }, + { + "var": "isMovingRight", + "state": "STRAFERIGHT" + }, + { + "var": "isMovingLeft", + "state": "STRAFELEFT" + }, + { + "var": "isTurningRight", + "state": "turnRight" + }, + { + "var": "isTurningLeft", + "state": "turnLeft" + }, + { + "var": "isFlying", + "state": "fly" + }, + { + "var": "isTakeoffStand", + "state": "takeoffStand" + }, + { + "var": "isTakeoffRun", + "state": "TAKEOFFRUN" + }, + { + "var": "isInAirStand", + "state": "inAirStand" + }, + { + "var": "isInAirRun", + "state": "INAIRRUN" + }, + { + "var": "isMovingRightHmd", + "state": "strafeRightHmd" + }, + { + "var": "isMovingLeftHmd", + "state": "strafeLeftHmd" + } + ] + }, + { + "id": "idleToWalkFwd", + "interpTarget": 12, + "interpDuration": 8, + "transitions": [ + { + "var": "idleToWalkFwdOnDone", + "state": "WALKFWD" + }, + { + "var": "isNotMoving", + "state": "idle" + }, + { + "var": "isMovingBackward", + "state": "WALKBWD" + }, + { + "var": "isMovingRight", + "state": "STRAFERIGHT" + }, + { + "var": "isMovingLeft", + "state": "STRAFELEFT" + }, + { + "var": "isTurningRight", + "state": "turnRight" + }, + { + "var": "isTurningLeft", + "state": "turnLeft" + }, + { + "var": "isFlying", + "state": "fly" + }, + { + "var": "isTakeoffStand", + "state": "takeoffStand" + }, + { + "var": "isTakeoffRun", + "state": "TAKEOFFRUN" + }, + { + "var": "isInAirStand", + "state": "inAirStand" + }, + { + "var": "isInAirRun", + "state": "INAIRRUN" + }, + { + "var": "isMovingRightHmd", + "state": "strafeRightHmd" + }, + { + "var": "isMovingLeftHmd", + "state": "strafeLeftHmd" + } + ] + }, + { + "id": "idleSettle", + "interpTarget": 15, + "interpDuration": 8, + "interpType": "snapshotPrev", + "transitions": [ + { + "var": "idleSettleOnDone", + "state": "idle" + }, + { + "var": "isMovingForward", + "state": "WALKFWD" + }, + { + "var": "isMovingBackward", + "state": "WALKBWD" + }, + { + "var": "isMovingRight", + "state": "STRAFERIGHT" + }, + { + "var": "isMovingLeft", + "state": "STRAFELEFT" + }, + { + "var": "isMovingRightHmd", + "state": "strafeRightHmd" + }, + { + "var": "isMovingLeftHmd", + "state": "strafeLeftHmd" + }, + { + "var": "isTurningRight", + "state": "turnRight" + }, + { + "var": "isTurningLeft", + "state": "turnLeft" + }, + { + "var": "isFlying", + "state": "fly" + }, + { + "var": "isTakeoffStand", + "state": "takeoffStand" + }, + { + "var": "isTakeoffRun", + "state": "TAKEOFFRUN" + }, + { + "var": "isInAirStand", + "state": "inAirStand" + }, + { + "var": "isInAirRun", + "state": "INAIRRUN" + } + ] + }, + { + "id": "WALKFWD", + "interpTarget": 35, + "interpDuration": 10, + "interpType": "snapshotPrev", + "transitions": [ + { + "var": "isNotMoving", + "state": "idleSettle" + }, + { + "var": "isMovingBackward", + "state": "WALKBWD" + }, + { + "var": "isMovingRight", + "state": "STRAFERIGHT" + }, + { + "var": "isMovingLeft", + "state": "STRAFELEFT" + }, + { + "var": "isTurningRight", + "state": "turnRight" + }, + { + "var": "isTurningLeft", + "state": "turnLeft" + }, + { + "var": "isFlying", + "state": "fly" + }, + { + "var": "isTakeoffStand", + "state": "takeoffStand" + }, + { + "var": "isTakeoffRun", + "state": "TAKEOFFRUN" + }, + { + "var": "isInAirStand", + "state": "inAirStand" + }, + { + "var": "isInAirRun", + "state": "INAIRRUN" + }, + { + "var": "isMovingRightHmd", + "state": "strafeRightHmd" + }, + { + "var": "isMovingLeftHmd", + "state": "strafeLeftHmd" + } + ] + }, + { + "id": "WALKBWD", + "interpTarget": 35, + "interpDuration": 10, + "interpType": "snapshotPrev", + "transitions": [ + { + "var": "isNotMoving", + "state": "idleSettle" + }, + { + "var": "isMovingForward", + "state": "WALKFWD" + }, + { + "var": "isMovingRight", + "state": "STRAFERIGHT" + }, + { + "var": "isMovingLeft", + "state": "STRAFELEFT" + }, + { + "var": "isTurningRight", + "state": "turnRight" + }, + { + "var": "isTurningLeft", + "state": "turnLeft" + }, + { + "var": "isFlying", + "state": "fly" + }, + { + "var": "isTakeoffStand", + "state": "takeoffStand" + }, + { + "var": "isTakeoffRun", + "state": "TAKEOFFRUN" + }, + { + "var": "isInAirStand", + "state": "inAirStand" + }, + { + "var": "isInAirRun", + "state": "INAIRRUN" + }, + { + "var": "isMovingRightHmd", + "state": "strafeRightHmd" + }, + { + "var": "isMovingLeftHmd", + "state": "strafeLeftHmd" + } + ] + }, + { + "id": "STRAFERIGHT", + "interpTarget": 25, + "interpDuration": 8, + "interpType": "snapshotPrev", + "transitions": [ + { + "var": "isNotMoving", + "state": "idleSettle" + }, + { + "var": "isMovingForward", + "state": "WALKFWD" + }, + { + "var": "isMovingBackward", + "state": "WALKBWD" + }, + { + "var": "isMovingLeft", + "state": "STRAFELEFT" + }, + { + "var": "isTurningRight", + "state": "turnRight" + }, + { + "var": "isTurningLeft", + "state": "turnLeft" + }, + { + "var": "isFlying", + "state": "fly" + }, + { + "var": "isTakeoffStand", + "state": "takeoffStand" + }, + { + "var": "isTakeoffRun", + "state": "TAKEOFFRUN" + }, + { + "var": "isInAirStand", + "state": "inAirStand" + }, + { + "var": "isInAirRun", + "state": "INAIRRUN" + }, + { + "var": "isMovingRightHmd", + "state": "strafeRightHmd" + }, + { + "var": "isMovingLeftHmd", + "state": "strafeLeftHmd" + } + ] + }, + { + "id": "STRAFELEFT", + "interpTarget": 25, + "interpDuration": 8, + "interpType": "snapshotPrev", + "transitions": [ + { + "var": "isNotMoving", + "state": "idleSettle" + }, + { + "var": "isMovingForward", + "state": "WALKFWD" + }, + { + "var": "isMovingBackward", + "state": "WALKBWD" + }, + { + "var": "isMovingRight", + "state": "STRAFERIGHT" + }, + { + "var": "isTurningRight", + "state": "turnRight" + }, + { + "var": "isTurningLeft", + "state": "turnLeft" + }, + { + "var": "isFlying", + "state": "fly" + }, + { + "var": "isTakeoffStand", + "state": "takeoffStand" + }, + { + "var": "isTakeoffRun", + "state": "TAKEOFFRUN" + }, + { + "var": "isInAirStand", + "state": "inAirStand" + }, + { + "var": "isInAirRun", + "state": "INAIRRUN" + }, + { + "var": "isMovingRightHmd", + "state": "strafeRightHmd" + }, + { + "var": "isMovingLeftHmd", + "state": "strafeLeftHmd" + } + ] + }, + { + "id": "turnRight", + "interpTarget": 6, + "interpDuration": 8, + "transitions": [ + { + "var": "isNotTurning", + "state": "idle" + }, + { + "var": "isMovingForward", + "state": "WALKFWD" + }, + { + "var": "isMovingBackward", + "state": "WALKBWD" + }, + { + "var": "isMovingRight", + "state": "STRAFERIGHT" + }, + { + "var": "isMovingLeft", + "state": "STRAFELEFT" + }, + { + "var": "isTurningLeft", + "state": "turnLeft" + }, + { + "var": "isFlying", + "state": "fly" + }, + { + "var": "isTakeoffStand", + "state": "takeoffStand" + }, + { + "var": "isTakeoffRun", + "state": "TAKEOFFRUN" + }, + { + "var": "isInAirStand", + "state": "inAirStand" + }, + { + "var": "isInAirRun", + "state": "INAIRRUN" + }, + { + "var": "isMovingRightHmd", + "state": "strafeRightHmd" + }, + { + "var": "isMovingLeftHmd", + "state": "strafeLeftHmd" + } + ] + }, + { + "id": "turnLeft", + "interpTarget": 6, + "interpDuration": 8, + "transitions": [ + { + "var": "isNotTurning", + "state": "idle" + }, + { + "var": "isMovingForward", + "state": "WALKFWD" + }, + { + "var": "isMovingBackward", + "state": "WALKBWD" + }, + { + "var": "isMovingRight", + "state": "STRAFERIGHT" + }, + { + "var": "isMovingLeft", + "state": "STRAFELEFT" + }, + { + "var": "isTurningRight", + "state": "turnRight" + }, + { + "var": "isFlying", + "state": "fly" + }, + { + "var": "isTakeoffStand", + "state": "takeoffStand" + }, + { + "var": "isTakeoffRun", + "state": "TAKEOFFRUN" + }, + { + "var": "isInAirStand", + "state": "inAirStand" + }, + { + "var": "isInAirRun", + "state": "INAIRRUN" + }, + { + "var": "isMovingRightHmd", + "state": "strafeRightHmd" + }, + { + "var": "isMovingLeftHmd", + "state": "strafeLeftHmd" + } + ] + }, + { + "id": "strafeRightHmd", + "interpTarget": 5, + "interpDuration": 8, + "interpType": "snapshotPrev", + "transitions": [ + { + "var": "isNotMoving", + "state": "idleSettle" + }, + { + "var": "isMovingForward", + "state": "WALKFWD" + }, + { + "var": "isMovingBackward", + "state": "WALKBWD" + }, + { + "var": "isMovingLeftHmd", + "state": "strafeLeftHmd" + }, + { + "var": "isMovingRight", + "state": "STRAFERIGHT" + }, + { + "var": "isMovingLeft", + "state": "STRAFELEFT" + }, + { + "var": "isTurningRight", + "state": "turnRight" + }, + { + "var": "isTurningLeft", + "state": "turnLeft" + }, + { + "var": "isFlying", + "state": "fly" + }, + { + "var": "isTakeoffStand", + "state": "takeoffStand" + }, + { + "var": "isTakeoffRun", + "state": "TAKEOFFRUN" + }, + { + "var": "isInAirStand", + "state": "inAirStand" + }, + { + "var": "isInAirRun", + "state": "INAIRRUN" + } + ] + }, + { + "id": "strafeLeftHmd", + "interpTarget": 5, + "interpDuration": 8, + "interpType": "snapshotPrev", + "transitions": [ + { + "var": "isNotMoving", + "state": "idleSettle" + }, + { + "var": "isMovingForward", + "state": "WALKFWD" + }, + { + "var": "isMovingBackward", + "state": "WALKBWD" + }, + { + "var": "isMovingRightHmd", + "state": "strafeRightHmd" + }, + { + "var": "isMovingRight", + "state": "STRAFERIGHT" + }, + { + "var": "isMovingLeft", + "state": "STRAFELEFT" + }, + { + "var": "isTurningRight", + "state": "turnRight" + }, + { + "var": "isTurningLeft", + "state": "turnLeft" + }, + { + "var": "isFlying", + "state": "fly" + }, + { + "var": "isTakeoffStand", + "state": "takeoffStand" + }, + { + "var": "isTakeoffRun", + "state": "TAKEOFFRUN" + }, + { + "var": "isInAirStand", + "state": "inAirStand" + }, + { + "var": "isInAirRun", + "state": "INAIRRUN" + } + ] + }, + { + "id": "fly", + "interpTarget": 6, + "interpDuration": 6, + "transitions": [ + { + "var": "isNotFlying", + "state": "idleSettle" + } + ] + }, + { + "id": "takeoffStand", + "interpTarget": 2, + "interpDuration": 2, + "transitions": [ + { + "var": "isNotTakeoff", + "state": "inAirStand" + } + ] + }, + { + "id": "TAKEOFFRUN", + "interpTarget": 2, + "interpDuration": 2, + "transitions": [ + { + "var": "isNotTakeoff", + "state": "INAIRRUN" + } + ] + }, + { + "id": "inAirStand", + "interpTarget": 3, + "interpDuration": 3, + "interpType": "snapshotPrev", + "transitions": [ + { + "var": "isNotInAir", + "state": "landStandImpact" + } + ] + }, + { + "id": "INAIRRUN", + "interpTarget": 3, + "interpDuration": 3, + "interpType": "snapshotPrev", + "transitions": [ + { + "var": "isNotInAir", + "state": "WALKFWD" + } + ] + }, + { + "id": "landStandImpact", + "interpTarget": 1, + "interpDuration": 1, + "transitions": [ + { + "var": "isFlying", + "state": "fly" + }, + { + "var": "isTakeoffStand", + "state": "takeoffStand" + }, + { + "var": "isTakeoffRun", + "state": "TAKEOFFRUN" + }, + { + "var": "landStandImpactOnDone", + "state": "landStand" + } + ] + }, + { + "id": "landStand", + "interpTarget": 1, + "interpDuration": 1, + "transitions": [ + { + "var": "isMovingForward", + "state": "WALKFWD" + }, + { + "var": "isMovingBackward", + "state": "WALKBWD" + }, + { + "var": "isMovingRight", + "state": "STRAFERIGHT" + }, + { + "var": "isMovingLeft", + "state": "STRAFELEFT" + }, + { + "var": "isTurningRight", + "state": "turnRight" + }, + { + "var": "isTurningLeft", + "state": "turnLeft" + }, + { + "var": "isFlying", + "state": "fly" + }, + { + "var": "isTakeoffStand", + "state": "takeoffStand" + }, + { + "var": "isTakeoffRun", + "state": "TAKEOFFRUN" + }, + { + "var": "isInAirStand", + "state": "inAirStand" + }, + { + "var": "isInAirRun", + "state": "INAIRRUN" + }, + { + "var": "landStandOnDone", + "state": "idle" + }, + { + "var": "isMovingRightHmd", + "state": "strafeRightHmd" + }, + { + "var": "isMovingLeftHmd", + "state": "strafeLeftHmd" + } + ] + }, + { + "id": "LANDRUN", + "interpTarget": 2, + "interpDuration": 2, + "transitions": [ + { + "var": "isFlying", + "state": "fly" + }, + { + "var": "isTakeoffStand", + "state": "takeoffStand" + }, + { + "var": "isTakeoffRun", + "state": "TAKEOFFRUN" + }, + { + "var": "landRunOnDone", + "state": "WALKFWD" + } + ] + } + ] }, "children": [ { - "id": "leftHandStateMachine", + "id": "idle", "type": "stateMachine", "data": { - "currentState": "leftHandGrasp", + "currentState": "idleStand", "states": [ { - "id": "leftHandGrasp", - "interpTarget": 3, - "interpDuration": 3, + "id": "idleStand", + "interpTarget": 6, + "interpDuration": 10, "transitions": [ { - "var": "isLeftIndexPoint", - "state": "leftIndexPoint" - }, - { - "var": "isLeftThumbRaise", - "state": "leftThumbRaise" - }, - { - "var": "isLeftIndexPointAndThumbRaise", - "state": "leftIndexPointAndThumbRaise" + "var": "isTalking", + "state": "idleTalk" } ] }, { - "id": "leftIndexPoint", - "interpTarget": 15, - "interpDuration": 3, + "id": "idleTalk", + "interpTarget": 6, + "interpDuration": 10, "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" + "var": "notIsTalking", + "state": "idleStand" } ] } @@ -556,1218 +1550,305 @@ }, "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": "mainStateMachine", - "type": "stateMachine", - "data": { - "outputJoints": [ "LeftFoot", "RightFoot" ], - "currentState": "idle", - "states": [ - { - "id": "idle", - "interpTarget": 20, - "interpDuration": 8, - "interpType": "snapshotPrev", - "transitions": [ - { - "var": "isMovingForward", - "state": "WALKFWD" - }, - { - "var": "isMovingBackward", - "state": "WALKBWD" - }, - { - "var": "isMovingRight", - "state": "STRAFERIGHT" - }, - { - "var": "isMovingLeft", - "state": "STRAFELEFT" - }, - { - "var": "isTurningRight", - "state": "turnRight" - }, - { - "var": "isTurningLeft", - "state": "turnLeft" - }, - { - "var": "isFlying", - "state": "fly" - }, - { - "var": "isTakeoffStand", - "state": "takeoffStand" - }, - { - "var": "isTakeoffRun", - "state": "TAKEOFFRUN" - }, - { - "var": "isInAirStand", - "state": "inAirStand" - }, - { - "var": "isInAirRun", - "state": "INAIRRUN" - }, - { - "var": "isMovingRightHmd", - "state": "strafeRightHmd" - }, - { - "var": "isMovingLeftHmd", - "state": "strafeLeftHmd" - } - ] - }, - { - "id": "idleToWalkFwd", - "interpTarget": 12, - "interpDuration": 8, - "transitions": [ - { - "var": "idleToWalkFwdOnDone", - "state": "WALKFWD" - }, - { - "var": "isNotMoving", - "state": "idle" - }, - { - "var": "isMovingBackward", - "state": "WALKBWD" - }, - { - "var": "isMovingRight", - "state": "STRAFERIGHT" - }, - { - "var": "isMovingLeft", - "state": "STRAFELEFT" - }, - { - "var": "isTurningRight", - "state": "turnRight" - }, - { - "var": "isTurningLeft", - "state": "turnLeft" - }, - { - "var": "isFlying", - "state": "fly" - }, - { - "var": "isTakeoffStand", - "state": "takeoffStand" - }, - { - "var": "isTakeoffRun", - "state": "TAKEOFFRUN" - }, - { - "var": "isInAirStand", - "state": "inAirStand" - }, - { - "var": "isInAirRun", - "state": "INAIRRUN" - }, - { - "var": "isMovingRightHmd", - "state": "strafeRightHmd" - }, - { - "var": "isMovingLeftHmd", - "state": "strafeLeftHmd" - } - ] - }, - { - "id": "idleSettle", - "interpTarget": 15, - "interpDuration": 8, - "interpType": "snapshotPrev", - "transitions": [ - { - "var": "idleSettleOnDone", - "state": "idle" - }, - { - "var": "isMovingForward", - "state": "WALKFWD" - }, - { - "var": "isMovingBackward", - "state": "WALKBWD" - }, - { - "var": "isMovingRight", - "state": "STRAFERIGHT" - }, - { - "var": "isMovingLeft", - "state": "STRAFELEFT" - }, - { - "var": "isMovingRightHmd", - "state": "strafeRightHmd" - }, - { - "var": "isMovingLeftHmd", - "state": "strafeLeftHmd" - }, - { - "var": "isTurningRight", - "state": "turnRight" - }, - { - "var": "isTurningLeft", - "state": "turnLeft" - }, - { - "var": "isFlying", - "state": "fly" - }, - { - "var": "isTakeoffStand", - "state": "takeoffStand" - }, - { - "var": "isTakeoffRun", - "state": "TAKEOFFRUN" - }, - { - "var": "isInAirStand", - "state": "inAirStand" - }, - { - "var": "isInAirRun", - "state": "INAIRRUN" - } - ] - }, - { - "id": "WALKFWD", - "interpTarget": 35, - "interpDuration": 10, - "interpType": "snapshotPrev", - "transitions": [ - { - "var": "isNotMoving", - "state": "idleSettle" - }, - { - "var": "isMovingBackward", - "state": "WALKBWD" - }, - { - "var": "isMovingRight", - "state": "STRAFERIGHT" - }, - { - "var": "isMovingLeft", - "state": "STRAFELEFT" - }, - { - "var": "isTurningRight", - "state": "turnRight" - }, - { - "var": "isTurningLeft", - "state": "turnLeft" - }, - { - "var": "isFlying", - "state": "fly" - }, - { - "var": "isTakeoffStand", - "state": "takeoffStand" - }, - { - "var": "isTakeoffRun", - "state": "TAKEOFFRUN" - }, - { - "var": "isInAirStand", - "state": "inAirStand" - }, - { - "var": "isInAirRun", - "state": "INAIRRUN" - }, - { - "var": "isMovingRightHmd", - "state": "strafeRightHmd" - }, - { - "var": "isMovingLeftHmd", - "state": "strafeLeftHmd" - } - ] - }, - { - "id": "WALKBWD", - "interpTarget": 35, - "interpDuration": 10, - "interpType": "snapshotPrev", - "transitions": [ - { - "var": "isNotMoving", - "state": "idleSettle" - }, - { - "var": "isMovingForward", - "state": "WALKFWD" - }, - { - "var": "isMovingRight", - "state": "STRAFERIGHT" - }, - { - "var": "isMovingLeft", - "state": "STRAFELEFT" - }, - { - "var": "isTurningRight", - "state": "turnRight" - }, - { - "var": "isTurningLeft", - "state": "turnLeft" - }, - { - "var": "isFlying", - "state": "fly" - }, - { - "var": "isTakeoffStand", - "state": "takeoffStand" - }, - { - "var": "isTakeoffRun", - "state": "TAKEOFFRUN" - }, - { - "var": "isInAirStand", - "state": "inAirStand" - }, - { - "var": "isInAirRun", - "state": "INAIRRUN" - }, - { - "var": "isMovingRightHmd", - "state": "strafeRightHmd" - }, - { - "var": "isMovingLeftHmd", - "state": "strafeLeftHmd" - } - ] - }, - { - "id": "STRAFERIGHT", - "interpTarget": 25, - "interpDuration": 8, - "interpType": "snapshotPrev", - "transitions": [ - { - "var": "isNotMoving", - "state": "idleSettle" - }, - { - "var": "isMovingForward", - "state": "WALKFWD" - }, - { - "var": "isMovingBackward", - "state": "WALKBWD" - }, - { - "var": "isMovingLeft", - "state": "STRAFELEFT" - }, - { - "var": "isTurningRight", - "state": "turnRight" - }, - { - "var": "isTurningLeft", - "state": "turnLeft" - }, - { - "var": "isFlying", - "state": "fly" - }, - { - "var": "isTakeoffStand", - "state": "takeoffStand" - }, - { - "var": "isTakeoffRun", - "state": "TAKEOFFRUN" - }, - { - "var": "isInAirStand", - "state": "inAirStand" - }, - { - "var": "isInAirRun", - "state": "INAIRRUN" - }, - { - "var": "isMovingRightHmd", - "state": "strafeRightHmd" - }, - { - "var": "isMovingLeftHmd", - "state": "strafeLeftHmd" - } - ] - }, - { - "id": "STRAFELEFT", - "interpTarget": 25, - "interpDuration": 8, - "interpType": "snapshotPrev", - "transitions": [ - { - "var": "isNotMoving", - "state": "idleSettle" - }, - { - "var": "isMovingForward", - "state": "WALKFWD" - }, - { - "var": "isMovingBackward", - "state": "WALKBWD" - }, - { - "var": "isMovingRight", - "state": "STRAFERIGHT" - }, - { - "var": "isTurningRight", - "state": "turnRight" - }, - { - "var": "isTurningLeft", - "state": "turnLeft" - }, - { - "var": "isFlying", - "state": "fly" - }, - { - "var": "isTakeoffStand", - "state": "takeoffStand" - }, - { - "var": "isTakeoffRun", - "state": "TAKEOFFRUN" - }, - { - "var": "isInAirStand", - "state": "inAirStand" - }, - { - "var": "isInAirRun", - "state": "INAIRRUN" - }, - { - "var": "isMovingRightHmd", - "state": "strafeRightHmd" - }, - { - "var": "isMovingLeftHmd", - "state": "strafeLeftHmd" - } - ] - }, - { - "id": "turnRight", - "interpTarget": 6, - "interpDuration": 8, - "transitions": [ - { - "var": "isNotTurning", - "state": "idle" - }, - { - "var": "isMovingForward", - "state": "WALKFWD" - }, - { - "var": "isMovingBackward", - "state": "WALKBWD" - }, - { - "var": "isMovingRight", - "state": "STRAFERIGHT" - }, - { - "var": "isMovingLeft", - "state": "STRAFELEFT" - }, - { - "var": "isTurningLeft", - "state": "turnLeft" - }, - { - "var": "isFlying", - "state": "fly" - }, - { - "var": "isTakeoffStand", - "state": "takeoffStand" - }, - { - "var": "isTakeoffRun", - "state": "TAKEOFFRUN" - }, - { - "var": "isInAirStand", - "state": "inAirStand" - }, - { - "var": "isInAirRun", - "state": "INAIRRUN" - }, - { - "var": "isMovingRightHmd", - "state": "strafeRightHmd" - }, - { - "var": "isMovingLeftHmd", - "state": "strafeLeftHmd" - } - ] - }, - { - "id": "turnLeft", - "interpTarget": 6, - "interpDuration": 8, - "transitions": [ - { - "var": "isNotTurning", - "state": "idle" - }, - { - "var": "isMovingForward", - "state": "WALKFWD" - }, - { - "var": "isMovingBackward", - "state": "WALKBWD" - }, - { - "var": "isMovingRight", - "state": "STRAFERIGHT" - }, - { - "var": "isMovingLeft", - "state": "STRAFELEFT" - }, - { - "var": "isTurningRight", - "state": "turnRight" - }, - { - "var": "isFlying", - "state": "fly" - }, - { - "var": "isTakeoffStand", - "state": "takeoffStand" - }, - { - "var": "isTakeoffRun", - "state": "TAKEOFFRUN" - }, - { - "var": "isInAirStand", - "state": "inAirStand" - }, - { - "var": "isInAirRun", - "state": "INAIRRUN" - }, - { - "var": "isMovingRightHmd", - "state": "strafeRightHmd" - }, - { - "var": "isMovingLeftHmd", - "state": "strafeLeftHmd" - } - ] - }, - { - "id": "strafeRightHmd", - "interpTarget": 5, - "interpDuration": 8, - "interpType": "snapshotPrev", - "transitions": [ - { - "var": "isNotMoving", - "state": "idleSettle" - }, - { - "var": "isMovingForward", - "state": "WALKFWD" - }, - { - "var": "isMovingBackward", - "state": "WALKBWD" - }, - { - "var": "isMovingLeftHmd", - "state": "strafeLeftHmd" - }, - { - "var": "isMovingRight", - "state": "STRAFERIGHT" - }, - { - "var": "isMovingLeft", - "state": "STRAFELEFT" - }, - { - "var": "isTurningRight", - "state": "turnRight" - }, - { - "var": "isTurningLeft", - "state": "turnLeft" - }, - { - "var": "isFlying", - "state": "fly" - }, - { - "var": "isTakeoffStand", - "state": "takeoffStand" - }, - { - "var": "isTakeoffRun", - "state": "TAKEOFFRUN" - }, - { - "var": "isInAirStand", - "state": "inAirStand" - }, - { - "var": "isInAirRun", - "state": "INAIRRUN" - } - ] - }, - { - "id": "strafeLeftHmd", - "interpTarget": 5, - "interpDuration": 8, - "interpType": "snapshotPrev", - "transitions": [ - { - "var": "isNotMoving", - "state": "idleSettle" - }, - { - "var": "isMovingForward", - "state": "WALKFWD" - }, - { - "var": "isMovingBackward", - "state": "WALKBWD" - }, - { - "var": "isMovingRightHmd", - "state": "strafeRightHmd" - }, - { - "var": "isMovingRight", - "state": "STRAFERIGHT" - }, - { - "var": "isMovingLeft", - "state": "STRAFELEFT" - }, - { - "var": "isTurningRight", - "state": "turnRight" - }, - { - "var": "isTurningLeft", - "state": "turnLeft" - }, - { - "var": "isFlying", - "state": "fly" - }, - { - "var": "isTakeoffStand", - "state": "takeoffStand" - }, - { - "var": "isTakeoffRun", - "state": "TAKEOFFRUN" - }, - { - "var": "isInAirStand", - "state": "inAirStand" - }, - { - "var": "isInAirRun", - "state": "INAIRRUN" - } - ] - }, - { - "id": "fly", - "interpTarget": 6, - "interpDuration": 6, - "transitions": [ - { - "var": "isNotFlying", - "state": "idleSettle" - } - ] - }, - { - "id": "takeoffStand", - "interpTarget": 2, - "interpDuration": 2, - "transitions": [ - { - "var": "isNotTakeoff", - "state": "inAirStand" - } - ] - }, - { - "id": "TAKEOFFRUN", - "interpTarget": 2, - "interpDuration": 2, - "transitions": [ - { - "var": "isNotTakeoff", - "state": "INAIRRUN" - } - ] - }, - { - "id": "inAirStand", - "interpTarget": 3, - "interpDuration": 3, - "interpType": "snapshotPrev", - "transitions": [ - { - "var": "isNotInAir", - "state": "landStandImpact" - } - ] - }, - { - "id": "INAIRRUN", - "interpTarget": 3, - "interpDuration": 3, - "interpType": "snapshotPrev", - "transitions": [ - { - "var": "isNotInAir", - "state": "WALKFWD" - } - ] - }, - { - "id": "landStandImpact", - "interpTarget": 1, - "interpDuration": 1, - "transitions": [ - { - "var": "isFlying", - "state": "fly" - }, - { - "var": "isTakeoffStand", - "state": "takeoffStand" - }, - { - "var": "isTakeoffRun", - "state": "TAKEOFFRUN" - }, - { - "var": "landStandImpactOnDone", - "state": "landStand" - } - ] - }, - { - "id": "landStand", - "interpTarget": 1, - "interpDuration": 1, - "transitions": [ - { - "var": "isMovingForward", - "state": "WALKFWD" - }, - { - "var": "isMovingBackward", - "state": "WALKBWD" - }, - { - "var": "isMovingRight", - "state": "STRAFERIGHT" - }, - { - "var": "isMovingLeft", - "state": "STRAFELEFT" - }, - { - "var": "isTurningRight", - "state": "turnRight" - }, - { - "var": "isTurningLeft", - "state": "turnLeft" - }, - { - "var": "isFlying", - "state": "fly" - }, - { - "var": "isTakeoffStand", - "state": "takeoffStand" - }, - { - "var": "isTakeoffRun", - "state": "TAKEOFFRUN" - }, - { - "var": "isInAirStand", - "state": "inAirStand" - }, - { - "var": "isInAirRun", - "state": "INAIRRUN" - }, - { - "var": "landStandOnDone", - "state": "idle" - }, - { - "var": "isMovingRightHmd", - "state": "strafeRightHmd" - }, - { - "var": "isMovingLeftHmd", - "state": "strafeLeftHmd" - } - ] - }, - { - "id": "LANDRUN", - "interpTarget": 2, - "interpDuration": 2, - "transitions": [ - { - "var": "isFlying", - "state": "fly" - }, - { - "var": "isTakeoffStand", - "state": "takeoffStand" - }, - { - "var": "isTakeoffRun", - "state": "TAKEOFFRUN" - }, - { - "var": "landRunOnDone", - "state": "WALKFWD" - } - ] - } - ] - }, - "children": [ - { - "id": "idle", - "type": "stateMachine", - "data": { - "currentState": "idleStand", - "states": [ - { - "id": "idleStand", - "interpTarget": 6, - "interpDuration": 10, - "transitions": [ - { - "var": "isTalking", - "state": "idleTalk" - } - ] - }, - { - "id": "idleTalk", - "interpTarget": 6, - "interpDuration": 10, - "transitions": [ - { - "var": "notIsTalking", - "state": "idleStand" - } - ] - } - ] - }, - "children": [ - { - "id": "idleStand", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/idle.fbx", - "startFrame": 0.0, - "endFrame": 300.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - }, - { - "id": "idleTalk", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/talk.fbx", - "startFrame": 0.0, - "endFrame": 800.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - } - ] - }, - { - "id": "WALKFWD", - "type": "blendLinearMove", - "data": { - "alpha": 0.0, - "desiredSpeed": 1.4, - "characteristicSpeeds": [ 0.5, 1.8, 2.3, 3.2, 4.5 ], - "alphaVar": "moveForwardAlpha", - "desiredSpeedVar": "moveForwardSpeed" - }, - "children": [ - { - "id": "walkFwdShort_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/walk_short_fwd.fbx", - "startFrame": 0.0, - "endFrame": 39.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - }, - { - "id": "walkFwdNormal_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/walk_fwd.fbx", - "startFrame": 0.0, - "endFrame": 30.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - }, - { - "id": "walkFwdFast_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/walk_fwd_fast.fbx", - "startFrame": 0.0, - "endFrame": 25.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - }, - { - "id": "walkFwdJog_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/jog_fwd.fbx", - "startFrame": 0.0, - "endFrame": 25.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - }, - { - "id": "walkFwdRun_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/run_fwd.fbx", - "startFrame": 0.0, - "endFrame": 21.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - } - ] - }, - { - "id": "idleToWalkFwd", + "id": "idleStand", "type": "clip", "data": { - "url": "qrc:///avatar/animations/idle_to_walk.fbx", - "startFrame": 1.0, - "endFrame": 13.0, - "timeScale": 1.0, - "loopFlag": false - }, - "children": [] - }, - { - "id": "idleSettle", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/settle_to_idle.fbx", - "startFrame": 1.0, - "endFrame": 59.0, - "timeScale": 1.0, - "loopFlag": false - }, - "children": [] - }, - { - "id": "WALKBWD", - "type": "blendLinearMove", - "data": { - "alpha": 0.0, - "desiredSpeed": 1.4, - "characteristicSpeeds": [ 0.6, 1.6, 2.3, 3.1 ], - "alphaVar": "moveBackwardAlpha", - "desiredSpeedVar": "moveBackwardSpeed" - }, - "children": [ - { - "id": "walkBwdShort_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/walk_short_bwd.fbx", - "startFrame": 0.0, - "endFrame": 38.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - }, - { - "id": "walkBwdFast_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/walk_bwd_fast.fbx", - "startFrame": 0.0, - "endFrame": 27.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - }, - { - "id": "jogBwd_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/jog_bwd.fbx", - "startFrame": 0.0, - "endFrame": 24.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - }, - { - "id": "runBwd_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/run_bwd.fbx", - "startFrame": 0.0, - "endFrame": 16.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - } - ] - }, - { - "id": "turnLeft", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/turn_left.fbx", + "url": "qrc:///avatar/animations/idle.fbx", "startFrame": 0.0, - "endFrame": 32.0, + "endFrame": 300.0, "timeScale": 1.0, "loopFlag": true }, "children": [] }, { - "id": "turnRight", + "id": "idleTalk", "type": "clip", "data": { - "url": "qrc:///avatar/animations/turn_left.fbx", + "url": "qrc:///avatar/animations/talk.fbx", "startFrame": 0.0, - "endFrame": 32.0, + "endFrame": 800.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + } + ] + }, + { + "id": "WALKFWD", + "type": "blendLinearMove", + "data": { + "alpha": 0.0, + "desiredSpeed": 1.4, + "characteristicSpeeds": [ 0.5, 1.8, 2.3, 3.2, 4.5 ], + "alphaVar": "moveForwardAlpha", + "desiredSpeedVar": "moveForwardSpeed" + }, + "children": [ + { + "id": "walkFwdShort_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/walk_short_fwd.fbx", + "startFrame": 0.0, + "endFrame": 39.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "walkFwdNormal_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/walk_fwd.fbx", + "startFrame": 0.0, + "endFrame": 30.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "walkFwdFast_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/walk_fwd_fast.fbx", + "startFrame": 0.0, + "endFrame": 25.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "walkFwdJog_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jog_fwd.fbx", + "startFrame": 0.0, + "endFrame": 25.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "walkFwdRun_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/run_fwd.fbx", + "startFrame": 0.0, + "endFrame": 21.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + } + ] + }, + { + "id": "idleToWalkFwd", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/idle_to_walk.fbx", + "startFrame": 1.0, + "endFrame": 13.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] + }, + { + "id": "idleSettle", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/settle_to_idle.fbx", + "startFrame": 1.0, + "endFrame": 59.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] + }, + { + "id": "WALKBWD", + "type": "blendLinearMove", + "data": { + "alpha": 0.0, + "desiredSpeed": 1.4, + "characteristicSpeeds": [ 0.6, 1.6, 2.3, 3.1 ], + "alphaVar": "moveBackwardAlpha", + "desiredSpeedVar": "moveBackwardSpeed" + }, + "children": [ + { + "id": "walkBwdShort_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/walk_short_bwd.fbx", + "startFrame": 0.0, + "endFrame": 38.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "walkBwdFast_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/walk_bwd_fast.fbx", + "startFrame": 0.0, + "endFrame": 27.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "jogBwd_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jog_bwd.fbx", + "startFrame": 0.0, + "endFrame": 24.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "runBwd_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/run_bwd.fbx", + "startFrame": 0.0, + "endFrame": 16.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + } + ] + }, + { + "id": "turnLeft", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/turn_left.fbx", + "startFrame": 0.0, + "endFrame": 32.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "turnRight", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/turn_left.fbx", + "startFrame": 0.0, + "endFrame": 32.0, + "timeScale": 1.0, + "loopFlag": true, + "mirrorFlag": true + }, + "children": [] + }, + { + "id": "STRAFELEFT", + "type": "blendLinearMove", + "data": { + "alpha": 0.0, + "desiredSpeed": 1.4, + "characteristicSpeeds": [ 0.1, 0.5, 1.0, 2.6, 3.0 ], + "alphaVar": "moveLateralAlpha", + "desiredSpeedVar": "moveLateralSpeed" + }, + "children": [ + { + "id": "strafeLeftShortStep_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/side_step_short_left.fbx", + "startFrame": 0.0, + "endFrame": 29.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "strafeLeftStep_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/side_step_left.fbx", + "startFrame": 0.0, + "endFrame": 20.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "strafeLeftWalk_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/walk_left.fbx", + "startFrame": 0.0, + "endFrame": 35.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "strafeLeftWalkFast_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/walk_left_fast.fbx", + "startFrame": 0.0, + "endFrame": 21.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "strafeLeftJog_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jog_left.fbx", + "startFrame": 0.0, + "endFrame": 24.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + } + ] + }, + { + "id": "STRAFERIGHT", + "type": "blendLinearMove", + "data": { + "alpha": 0.0, + "desiredSpeed": 1.4, + "characteristicSpeeds": [ 0.1, 0.5, 1.0, 2.6, 3.0 ], + "alphaVar": "moveLateralAlpha", + "desiredSpeedVar": "moveLateralSpeed" + }, + "children": [ + { + "id": "strafeRightShortStep_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/side_step_short_left.fbx", + "startFrame": 0.0, + "endFrame": 29.0, "timeScale": 1.0, "loopFlag": true, "mirrorFlag": true @@ -1775,275 +1856,256 @@ "children": [] }, { - "id": "STRAFELEFT", - "type": "blendLinearMove", - "data": { - "alpha": 0.0, - "desiredSpeed": 1.4, - "characteristicSpeeds": [ 0.1, 0.5, 1.0, 2.6, 3.0 ], - "alphaVar": "moveLateralAlpha", - "desiredSpeedVar": "moveLateralSpeed" - }, - "children": [ - { - "id": "strafeLeftShortStep_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/side_step_short_left.fbx", - "startFrame": 0.0, - "endFrame": 29.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - }, - { - "id": "strafeLeftStep_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/side_step_left.fbx", - "startFrame": 0.0, - "endFrame": 20.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - }, - { - "id": "strafeLeftWalk_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/walk_left.fbx", - "startFrame": 0.0, - "endFrame": 35.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - }, - { - "id": "strafeLeftWalkFast_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/walk_left_fast.fbx", - "startFrame": 0.0, - "endFrame": 21.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - }, - { - "id": "strafeLeftJog_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/jog_left.fbx", - "startFrame": 0.0, - "endFrame": 24.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - } - ] - }, - { - "id": "STRAFERIGHT", - "type": "blendLinearMove", - "data": { - "alpha": 0.0, - "desiredSpeed": 1.4, - "characteristicSpeeds": [ 0.1, 0.5, 1.0, 2.6, 3.0 ], - "alphaVar": "moveLateralAlpha", - "desiredSpeedVar": "moveLateralSpeed" - }, - "children": [ - { - "id": "strafeRightShortStep_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/side_step_short_left.fbx", - "startFrame": 0.0, - "endFrame": 29.0, - "timeScale": 1.0, - "loopFlag": true, - "mirrorFlag": true - }, - "children": [] - }, - { - "id": "strafeRightStep_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/side_step_left.fbx", - "startFrame": 0.0, - "endFrame": 20.0, - "timeScale": 1.0, - "loopFlag": true, - "mirrorFlag": true - }, - "children": [] - }, - { - "id": "strafeRightWalk_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/walk_left.fbx", - "startFrame": 0.0, - "endFrame": 35.0, - "timeScale": 1.0, - "loopFlag": true, - "mirrorFlag": true - }, - "children": [] - }, - { - "id": "strafeRightFast_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/walk_left_fast.fbx", - "startFrame": 0.0, - "endFrame": 21.0, - "timeScale": 1.0, - "loopFlag": true, - "mirrorFlag": true - }, - "children": [] - }, - { - "id": "strafeRightJog_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/jog_left.fbx", - "startFrame": 0.0, - "endFrame": 24.0, - "timeScale": 1.0, - "loopFlag": true, - "mirrorFlag": true - }, - "children": [] - } - ] - }, - { - "id": "strafeLeftHmd", - "type": "blendLinearMove", - "data": { - "alpha": 0.0, - "desiredSpeed": 1.4, - "characteristicSpeeds": [ 0, 0.5, 2.5 ], - "alphaVar": "moveLateralAlpha", - "desiredSpeedVar": "moveLateralSpeed" - }, - "children": [ - { - "id": "stepLeftShort_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/side_step_short_left.fbx", - "startFrame": 0.0, - "endFrame": 29.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - }, - { - "id": "stepLeft_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/side_step_left.fbx", - "startFrame": 0.0, - "endFrame": 20.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - }, - { - "id": "strafeLeftAnim_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/side_step_left_fast.fbx", - "startFrame": 0.0, - "endFrame": 16.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - } - ] - }, - { - "id": "strafeRightHmd", - "type": "blendLinearMove", - "data": { - "alpha": 0.0, - "desiredSpeed": 1.4, - "characteristicSpeeds": [ 0, 0.5, 2.5 ], - "alphaVar": "moveLateralAlpha", - "desiredSpeedVar": "moveLateralSpeed" - }, - "children": [ - { - "id": "stepRightShort_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/side_step_short_left.fbx", - "startFrame": 0.0, - "endFrame": 29.0, - "timeScale": 1.0, - "loopFlag": true, - "mirrorFlag": true - }, - "children": [] - }, - { - "id": "stepRight_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/side_step_left.fbx", - "startFrame": 0.0, - "endFrame": 20.0, - "timeScale": 1.0, - "loopFlag": true, - "mirrorFlag": true - }, - "children": [] - }, - { - "id": "strafeRightAnim_c", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/side_step_left_fast.fbx", - "startFrame": 0.0, - "endFrame": 16.0, - "timeScale": 1.0, - "loopFlag": true, - "mirrorFlag": true - }, - "children": [] - } - ] - }, - { - "id": "fly", + "id": "strafeRightStep_c", "type": "clip", "data": { - "url": "qrc:///avatar/animations/fly.fbx", - "startFrame": 1.0, - "endFrame": 80.0, + "url": "qrc:///avatar/animations/side_step_left.fbx", + "startFrame": 0.0, + "endFrame": 20.0, + "timeScale": 1.0, + "loopFlag": true, + "mirrorFlag": true + }, + "children": [] + }, + { + "id": "strafeRightWalk_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/walk_left.fbx", + "startFrame": 0.0, + "endFrame": 35.0, + "timeScale": 1.0, + "loopFlag": true, + "mirrorFlag": true + }, + "children": [] + }, + { + "id": "strafeRightFast_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/walk_left_fast.fbx", + "startFrame": 0.0, + "endFrame": 21.0, + "timeScale": 1.0, + "loopFlag": true, + "mirrorFlag": true + }, + "children": [] + }, + { + "id": "strafeRightJog_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jog_left.fbx", + "startFrame": 0.0, + "endFrame": 24.0, + "timeScale": 1.0, + "loopFlag": true, + "mirrorFlag": true + }, + "children": [] + } + ] + }, + { + "id": "strafeLeftHmd", + "type": "blendLinearMove", + "data": { + "alpha": 0.0, + "desiredSpeed": 1.4, + "characteristicSpeeds": [ 0, 0.5, 2.5 ], + "alphaVar": "moveLateralAlpha", + "desiredSpeedVar": "moveLateralSpeed" + }, + "children": [ + { + "id": "stepLeftShort_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/side_step_short_left.fbx", + "startFrame": 0.0, + "endFrame": 29.0, "timeScale": 1.0, "loopFlag": true }, "children": [] }, { - "id": "takeoffStand", + "id": "stepLeft_c", "type": "clip", "data": { - "url": "qrc:///avatar/animations/jump_standing_launch.fbx", + "url": "qrc:///avatar/animations/side_step_left.fbx", + "startFrame": 0.0, + "endFrame": 20.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "strafeLeftAnim_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/side_step_left_fast.fbx", + "startFrame": 0.0, + "endFrame": 16.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + } + ] + }, + { + "id": "strafeRightHmd", + "type": "blendLinearMove", + "data": { + "alpha": 0.0, + "desiredSpeed": 1.4, + "characteristicSpeeds": [ 0, 0.5, 2.5 ], + "alphaVar": "moveLateralAlpha", + "desiredSpeedVar": "moveLateralSpeed" + }, + "children": [ + { + "id": "stepRightShort_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/side_step_short_left.fbx", + "startFrame": 0.0, + "endFrame": 29.0, + "timeScale": 1.0, + "loopFlag": true, + "mirrorFlag": true + }, + "children": [] + }, + { + "id": "stepRight_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/side_step_left.fbx", + "startFrame": 0.0, + "endFrame": 20.0, + "timeScale": 1.0, + "loopFlag": true, + "mirrorFlag": true + }, + "children": [] + }, + { + "id": "strafeRightAnim_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/side_step_left_fast.fbx", + "startFrame": 0.0, + "endFrame": 16.0, + "timeScale": 1.0, + "loopFlag": true, + "mirrorFlag": true + }, + "children": [] + } + ] + }, + { + "id": "fly", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/fly.fbx", + "startFrame": 1.0, + "endFrame": 80.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "takeoffStand", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jump_standing_launch.fbx", + "startFrame": 2.0, + "endFrame": 16.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] + }, + { + "id": "TAKEOFFRUN", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jump_running_launch_land.fbx", + "startFrame": 4.0, + "endFrame": 15.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] + }, + { + "id": "inAirStand", + "type": "blendLinear", + "data": { + "alpha": 0.0, + "alphaVar": "inAirAlpha" + }, + "children": [ + { + "id": "inAirStandPreApex", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jump_standing_apex.fbx", + "startFrame": 0.0, + "endFrame": 0.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] + }, + { + "id": "inAirStandApex", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jump_standing_apex.fbx", + "startFrame": 1.0, + "endFrame": 1.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] + }, + { + "id": "inAirStandPostApex", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jump_standing_apex.fbx", "startFrame": 2.0, + "endFrame": 2.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] + } + ] + }, + { + "id": "INAIRRUN", + "type": "blendLinear", + "data": { + "alpha": 0.0, + "alphaVar": "inAirAlpha" + }, + "children": [ + { + "id": "inAirRunPreApex", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jump_running_launch_land.fbx", + "startFrame": 16.0, "endFrame": 16.0, "timeScale": 1.0, "loopFlag": false @@ -2051,146 +2113,66 @@ "children": [] }, { - "id": "TAKEOFFRUN", + "id": "inAirRunApex", "type": "clip", "data": { "url": "qrc:///avatar/animations/jump_running_launch_land.fbx", - "startFrame": 4.0, - "endFrame": 15.0, + "startFrame": 22.0, + "endFrame": 22.0, "timeScale": 1.0, "loopFlag": false }, "children": [] }, { - "id": "inAirStand", - "type": "blendLinear", - "data": { - "alpha": 0.0, - "alphaVar": "inAirAlpha" - }, - "children": [ - { - "id": "inAirStandPreApex", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/jump_standing_apex.fbx", - "startFrame": 0.0, - "endFrame": 0.0, - "timeScale": 1.0, - "loopFlag": false - }, - "children": [] - }, - { - "id": "inAirStandApex", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/jump_standing_apex.fbx", - "startFrame": 1.0, - "endFrame": 1.0, - "timeScale": 1.0, - "loopFlag": false - }, - "children": [] - }, - { - "id": "inAirStandPostApex", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/jump_standing_apex.fbx", - "startFrame": 2.0, - "endFrame": 2.0, - "timeScale": 1.0, - "loopFlag": false - }, - "children": [] - } - ] - }, - { - "id": "INAIRRUN", - "type": "blendLinear", - "data": { - "alpha": 0.0, - "alphaVar": "inAirAlpha" - }, - "children": [ - { - "id": "inAirRunPreApex", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/jump_running_launch_land.fbx", - "startFrame": 16.0, - "endFrame": 16.0, - "timeScale": 1.0, - "loopFlag": false - }, - "children": [] - }, - { - "id": "inAirRunApex", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/jump_running_launch_land.fbx", - "startFrame": 22.0, - "endFrame": 22.0, - "timeScale": 1.0, - "loopFlag": false - }, - "children": [] - }, - { - "id": "inAirRunPostApex", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/jump_running_launch_land.fbx", - "startFrame": 33.0, - "endFrame": 33.0, - "timeScale": 1.0, - "loopFlag": false - }, - "children": [] - } - ] - }, - { - "id": "landStandImpact", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/jump_standing_land_settle.fbx", - "startFrame": 1.0, - "endFrame": 6.0, - "timeScale": 1.0, - "loopFlag": false - }, - "children": [] - }, - { - "id": "landStand", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/jump_standing_land_settle.fbx", - "startFrame": 6.0, - "endFrame": 68.0, - "timeScale": 1.0, - "loopFlag": false - }, - "children": [] - }, - { - "id": "LANDRUN", + "id": "inAirRunPostApex", "type": "clip", "data": { "url": "qrc:///avatar/animations/jump_running_launch_land.fbx", - "startFrame": 29.0, - "endFrame": 40.0, + "startFrame": 33.0, + "endFrame": 33.0, "timeScale": 1.0, "loopFlag": false }, "children": [] } ] + }, + { + "id": "landStandImpact", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jump_standing_land_settle.fbx", + "startFrame": 1.0, + "endFrame": 6.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] + }, + { + "id": "landStand", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jump_standing_land_settle.fbx", + "startFrame": 6.0, + "endFrame": 68.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] + }, + { + "id": "LANDRUN", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jump_running_launch_land.fbx", + "startFrame": 29.0, + "endFrame": 40.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] } ] } From cf8f9fa1b68eabd9c1e75a47af685f126b95218d Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Mon, 4 Feb 2019 11:28:42 -0700 Subject: [PATCH 044/112] Threads created correctly --- interface/src/avatar/AvatarManager.cpp | 103 ++++++++++++++++++ interface/src/avatar/AvatarManager.h | 9 ++ libraries/animation/src/Rig.cpp | 6 +- libraries/animation/src/Rig.h | 3 + .../src/avatars-renderer/Avatar.h | 3 + libraries/entities/src/EntityTree.cpp | 6 + libraries/entities/src/EntityTree.h | 1 + 7 files changed, 129 insertions(+), 2 deletions(-) diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index 1eb87c16f0..c9e099df21 100755 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -760,6 +760,109 @@ RayToAvatarIntersectionResult AvatarManager::findRayIntersectionVector(const Pic return result; } +RayToAvatarIntersectionResult AvatarManager::findRayIntersectionOld(const PickRay& ray, + const QScriptValue& avatarIdsToInclude, + const QScriptValue& avatarIdsToDiscard) { + QVector avatarsToInclude = qVectorEntityItemIDFromScriptValue(avatarIdsToInclude); + QVector avatarsToDiscard = qVectorEntityItemIDFromScriptValue(avatarIdsToDiscard); + + return findRayIntersectionVectorOld(ray, avatarsToInclude, avatarsToDiscard); +} + +RayToAvatarIntersectionResult AvatarManager::findRayIntersectionVectorOld(const PickRay& ray, + const QVector& avatarsToInclude, + const QVector& avatarsToDiscard) { + RayToAvatarIntersectionResult result; + if (QThread::currentThread() != thread()) { + BLOCKING_INVOKE_METHOD(const_cast(this), "findRayIntersectionVector", + Q_RETURN_ARG(RayToAvatarIntersectionResult, result), + Q_ARG(const PickRay&, ray), + Q_ARG(const QVector&, avatarsToInclude), + Q_ARG(const QVector&, avatarsToDiscard)); + return result; + } + + // It's better to intersect the ray against the avatar's actual mesh, but this is currently difficult to + // do, because the transformed mesh data only exists over in GPU-land. As a compromise, this code + // intersects against the avatars capsule and then against the (T-pose) mesh. The end effect is that picking + // against the avatar is sort-of right, but you likely wont be able to pick against the arms. + + // TODO -- find a way to extract transformed avatar mesh data from the rendering engine. + + std::vector sortedAvatars; + auto avatarHashCopy = getHashCopy(); + for (auto avatarData : avatarHashCopy) { + auto avatar = std::static_pointer_cast(avatarData); + if ((avatarsToInclude.size() > 0 && !avatarsToInclude.contains(avatar->getID())) || + (avatarsToDiscard.size() > 0 && avatarsToDiscard.contains(avatar->getID()))) { + continue; + } + + float distance = FLT_MAX; +#if 0 + // if we weren't picking against the capsule, we would want to pick against the avatarBounds... + SkeletonModelPointer avatarModel = avatar->getSkeletonModel(); + AABox avatarBounds = avatarModel->getRenderableMeshBound(); + if (avatarBounds.contains(ray.origin)) { + distance = 0.0f; + } + else { + float boundDistance = FLT_MAX; + BoxFace face; + glm::vec3 surfaceNormal; + if (avatarBounds.findRayIntersection(ray.origin, ray.direction, boundDistance, face, surfaceNormal)) { + distance = boundDistance; + } + } +#else + glm::vec3 start; + glm::vec3 end; + float radius; + avatar->getCapsule(start, end, radius); + findRayCapsuleIntersection(ray.origin, ray.direction, start, end, radius, distance); +#endif + + if (distance < FLT_MAX) { + sortedAvatars.emplace_back(distance, avatar); + } + } + + if (sortedAvatars.size() > 1) { + static auto comparator = [](const SortedAvatar& left, const SortedAvatar& right) { return left.first < right.first; }; + std::sort(sortedAvatars.begin(), sortedAvatars.end(), comparator); + } + + for (auto it = sortedAvatars.begin(); it != sortedAvatars.end(); ++it) { + const SortedAvatar& sortedAvatar = *it; + // We can exit once avatarCapsuleDistance > bestDistance + if (sortedAvatar.first > result.distance) { + break; + } + + float distance = FLT_MAX; + BoxFace face; + glm::vec3 surfaceNormal; + QVariantMap extraInfo; + SkeletonModelPointer avatarModel = sortedAvatar.second->getSkeletonModel(); + if (avatarModel->findRayIntersectionAgainstSubMeshes(ray.origin, ray.direction, distance, face, surfaceNormal, extraInfo, true)) { + if (distance < result.distance) { + result.intersects = true; + result.avatarID = sortedAvatar.second->getID(); + result.distance = distance; + result.face = face; + result.surfaceNormal = surfaceNormal; + result.extraInfo = extraInfo; + } + } + } + + if (result.intersects) { + result.intersection = ray.origin + ray.direction * result.distance; + } + + return result; +} + ParabolaToAvatarIntersectionResult AvatarManager::findParabolaIntersectionVector(const PickParabola& pick, const QVector& avatarsToInclude, const QVector& avatarsToDiscard) { diff --git a/interface/src/avatar/AvatarManager.h b/interface/src/avatar/AvatarManager.h index 50d9e80e8b..66f28206e0 100644 --- a/interface/src/avatar/AvatarManager.h +++ b/interface/src/avatar/AvatarManager.h @@ -157,6 +157,15 @@ public: const QVector& avatarsToDiscard, bool pickAgainstMesh); + Q_INVOKABLE RayToAvatarIntersectionResult findRayIntersectionOld(const PickRay& ray, + const QScriptValue& avatarIdsToInclude = QScriptValue(), + const QScriptValue& avatarIdsToDiscard = QScriptValue()); + + Q_INVOKABLE RayToAvatarIntersectionResult findRayIntersectionVectorOld(const PickRay& ray, + const QVector& avatarsToInclude, + const QVector& avatarsToDiscard); + + /**jsdoc * @function AvatarManager.findParabolaIntersectionVector * @param {PickParabola} pick diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index bc4dca54f2..8a05bdd018 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -34,7 +34,6 @@ #include "IKTarget.h" #include "PathUtils.h" - static int nextRigId = 1; static std::map rigRegistry; static std::mutex rigRegistryMutex; @@ -1871,7 +1870,7 @@ void Rig::initAnimGraph(const QUrl& url) { auto roleState = roleAnimState.second; overrideRoleAnimation(roleState.role, roleState.url, roleState.fps, roleState.loop, roleState.firstFrame, roleState.lastFrame); } - + _flow.setRig(this); emit onLoadComplete(); }); connect(_animLoader.get(), &AnimNodeLoader::error, [url](int error, QString str) { @@ -1903,6 +1902,9 @@ void Rig::initAnimGraph(const QUrl& url) { connect(_networkLoader.get(), &AnimNodeLoader::error, [networkUrl](int error, QString str) { qCritical(animation) << "Error loading: code = " << error << "str =" << str; }); + connect(this, &Rig::onLoadComplete, [&]() { + _flow.calculateConstraints(); + }); } } diff --git a/libraries/animation/src/Rig.h b/libraries/animation/src/Rig.h index 41c25a3c3e..9bd2ed528a 100644 --- a/libraries/animation/src/Rig.h +++ b/libraries/animation/src/Rig.h @@ -25,6 +25,7 @@ #include "AnimNodeLoader.h" #include "SimpleMovingAverage.h" #include "AnimUtil.h" +#include "Flow.h" class Rig; class AnimInverseKinematics; @@ -233,6 +234,7 @@ public: const AnimContext::DebugAlphaMap& getDebugAlphaMap() const { return _lastContext.getDebugAlphaMap(); } const AnimVariantMap& getAnimVars() const { return _lastAnimVars; } const AnimContext::DebugStateMachineMap& getStateMachineMap() const { return _lastContext.getStateMachineMap(); } + void computeFlowSkeleton() { _flow.calculateConstraints(); } signals: void onLoadComplete(); @@ -424,6 +426,7 @@ protected: SnapshotBlendPoseHelper _hipsBlendHelper; ControllerParameters _previousControllerParameters; + Flow _flow; }; #endif /* defined(__hifi__Rig__) */ diff --git a/libraries/avatars-renderer/src/avatars-renderer/Avatar.h b/libraries/avatars-renderer/src/avatars-renderer/Avatar.h index b43fe012b7..4ba2ffc07d 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/Avatar.h +++ b/libraries/avatars-renderer/src/avatars-renderer/Avatar.h @@ -35,6 +35,7 @@ #include "MetaModelPayload.h" #include "MultiSphereShape.h" +#include "Flow.h" namespace render { template <> const ItemKey payloadGetKey(const AvatarSharedPointer& avatar); @@ -285,6 +286,8 @@ public: */ Q_INVOKABLE glm::quat jointToWorldRotation(const glm::quat& rotation, const int jointIndex = -1) const; + Q_INVOKABLE void callFlow() { _skeletonModel->getRig().computeFlowSkeleton(); }; + virtual void setSkeletonModelURL(const QUrl& skeletonModelURL) override; virtual void setAttachmentData(const QVector& attachmentData) override; diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index 954462a9f2..47064bdbd3 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -2943,6 +2943,12 @@ int EntityTree::getJointIndex(const QUuid& entityID, const QString& name) const } return entity->getJointIndex(name); } +void EntityTree::callFlowSkeleton(const QUuid& entityID) { + /* + EntityTree* nonConstThis = const_cast(this); + EntityItemPointer entity = nonConstThis->findEntityByEntityItemID(entityID); + */ +} QStringList EntityTree::getJointNames(const QUuid& entityID) const { EntityTree* nonConstThis = const_cast(this); diff --git a/libraries/entities/src/EntityTree.h b/libraries/entities/src/EntityTree.h index f9b7b8d67f..cc80083e0d 100644 --- a/libraries/entities/src/EntityTree.h +++ b/libraries/entities/src/EntityTree.h @@ -240,6 +240,7 @@ public: // these are used to call through to EntityItems Q_INVOKABLE int getJointIndex(const QUuid& entityID, const QString& name) const; Q_INVOKABLE QStringList getJointNames(const QUuid& entityID) const; + Q_INVOKABLE void callFlowSkeleton(const QUuid& entityID); void knowAvatarID(QUuid avatarID) { _avatarIDs += avatarID; } void forgetAvatarID(QUuid avatarID) { _avatarIDs -= avatarID; } From a04e6d55ff50834467944beb1cd08b3ca22af977 Mon Sep 17 00:00:00 2001 From: amantley Date: Mon, 4 Feb 2019 13:31:36 -0800 Subject: [PATCH 045/112] enabled/disable ik now works for the new animspline json --- libraries/animation/src/AnimSplineIK.cpp | 4 ++-- libraries/animation/src/Rig.cpp | 28 ++++++++++++++++++------ 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/libraries/animation/src/AnimSplineIK.cpp b/libraries/animation/src/AnimSplineIK.cpp index 4dab904c05..bf329ef055 100644 --- a/libraries/animation/src/AnimSplineIK.cpp +++ b/libraries/animation/src/AnimSplineIK.cpp @@ -82,7 +82,7 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const AnimPoseVec underPoses = _children[0]->evaluate(animVars, context, dt, triggersOut); // if we don't have a skeleton, or jointName lookup failed or the spline alpha is 0 or there are no underposes. - if (!_skeleton || _baseJointIndex == -1 || _midJointIndex == -1 || _tipJointIndex == -1 || alpha == 0.0f || underPoses.size() == 0) { + if (!_skeleton || _baseJointIndex == -1 || _midJointIndex == -1 || _tipJointIndex == -1 || alpha < EPSILON || underPoses.size() == 0) { // pass underPoses through unmodified. _poses = underPoses; return _poses; @@ -474,4 +474,4 @@ void AnimSplineIK::beginInterp(InterpType interpType, const AnimChain& chain) { _interpType = interpType; _interpAlphaVel = FRAMES_PER_SECOND / _interpDuration; _interpAlpha = 0.0f; -} \ No newline at end of file +} diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index 713f9bc385..2faeddaa4f 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -1068,16 +1068,30 @@ void Rig::computeMotionAnimationState(float deltaTime, const glm::vec3& worldPos t += deltaTime; - if (_enableInverseKinematics != _lastEnableInverseKinematics) { - if (_enableInverseKinematics) { - _animVars.set("ikOverlayAlpha", 1.0f); - } else { - _animVars.set("ikOverlayAlpha", 0.0f); - } + if (_enableInverseKinematics) { + _animVars.set("splineIKEnabled", true); + _animVars.set("leftHandIKEnabled", true); + _animVars.set("rightHandIKEnabled", true); + _animVars.set("leftFootIKEnabled", true); + _animVars.set("rightFootIKEnabled", true); + _animVars.set("leftHandPoleVectorEnabled", true); + _animVars.set("rightHandPoleVectorEnabled", true); + _animVars.set("leftFootPoleVectorEnabled", true); + _animVars.set("rightFootPoleVectorEnabled", true); + } else { + _animVars.set("splineIKEnabled", false); + _animVars.set("leftHandIKEnabled", false); + _animVars.set("rightHandIKEnabled", false); + _animVars.set("leftFootIKEnabled", false); + _animVars.set("rightFootIKEnabled", false); + _animVars.set("leftHandPoleVectorEnabled", false); + _animVars.set("rightHandPoleVectorEnabled", false); + _animVars.set("leftFootPoleVectorEnabled", false); + _animVars.set("rightFootPoleVectorEnabled", false); } _lastEnableInverseKinematics = _enableInverseKinematics; - } + } _lastForward = forward; _lastPosition = worldPosition; _lastVelocity = workingVelocity; From 78d6e42fc85725227be101d3c06fb3bbec2e5c03 Mon Sep 17 00:00:00 2001 From: amantley Date: Mon, 4 Feb 2019 13:42:19 -0800 Subject: [PATCH 046/112] made the ik enable/disable work for the old animIK node json --- libraries/animation/src/Rig.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index 2faeddaa4f..f366c08cfe 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -1069,6 +1069,10 @@ void Rig::computeMotionAnimationState(float deltaTime, const glm::vec3& worldPos t += deltaTime; if (_enableInverseKinematics) { + + // animIK node json + _animVars.set("ikOverlayAlpha", 1.0f); + // animSpline json _animVars.set("splineIKEnabled", true); _animVars.set("leftHandIKEnabled", true); _animVars.set("rightHandIKEnabled", true); @@ -1079,6 +1083,9 @@ void Rig::computeMotionAnimationState(float deltaTime, const glm::vec3& worldPos _animVars.set("leftFootPoleVectorEnabled", true); _animVars.set("rightFootPoleVectorEnabled", true); } else { + // animIK node json + _animVars.set("ikOverlayAlpha", 0.0f); + // animSpline json _animVars.set("splineIKEnabled", false); _animVars.set("leftHandIKEnabled", false); _animVars.set("rightHandIKEnabled", false); From 031dd5639b69553fae579f4ded72f725b8538365 Mon Sep 17 00:00:00 2001 From: amantley Date: Mon, 4 Feb 2019 14:46:52 -0800 Subject: [PATCH 047/112] fixed pole vector over writing with the old json --- libraries/animation/src/Rig.cpp | 8 -------- 1 file changed, 8 deletions(-) diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index f366c08cfe..faddfdebb3 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -1069,23 +1069,16 @@ void Rig::computeMotionAnimationState(float deltaTime, const glm::vec3& worldPos t += deltaTime; if (_enableInverseKinematics) { - - // animIK node json _animVars.set("ikOverlayAlpha", 1.0f); - // animSpline json _animVars.set("splineIKEnabled", true); _animVars.set("leftHandIKEnabled", true); _animVars.set("rightHandIKEnabled", true); _animVars.set("leftFootIKEnabled", true); _animVars.set("rightFootIKEnabled", true); - _animVars.set("leftHandPoleVectorEnabled", true); - _animVars.set("rightHandPoleVectorEnabled", true); _animVars.set("leftFootPoleVectorEnabled", true); _animVars.set("rightFootPoleVectorEnabled", true); } else { - // animIK node json _animVars.set("ikOverlayAlpha", 0.0f); - // animSpline json _animVars.set("splineIKEnabled", false); _animVars.set("leftHandIKEnabled", false); _animVars.set("rightHandIKEnabled", false); @@ -1097,7 +1090,6 @@ void Rig::computeMotionAnimationState(float deltaTime, const glm::vec3& worldPos _animVars.set("rightFootPoleVectorEnabled", false); } _lastEnableInverseKinematics = _enableInverseKinematics; - } _lastForward = forward; _lastPosition = worldPosition; From 3e553f015c7f5f6b87d79cd0980b8e88b1e6c321 Mon Sep 17 00:00:00 2001 From: amantley Date: Tue, 5 Feb 2019 15:54:37 -0800 Subject: [PATCH 048/112] added the arm ik files to the repo, this is for the shoulder and elbow extensions --- libraries/animation/src/AnimArmIK.cpp | 40 +++++++++++++++++++++++++++ libraries/animation/src/AnimArmIK.h | 34 +++++++++++++++++++++++ 2 files changed, 74 insertions(+) create mode 100644 libraries/animation/src/AnimArmIK.cpp create mode 100644 libraries/animation/src/AnimArmIK.h diff --git a/libraries/animation/src/AnimArmIK.cpp b/libraries/animation/src/AnimArmIK.cpp new file mode 100644 index 0000000000..202e8c8420 --- /dev/null +++ b/libraries/animation/src/AnimArmIK.cpp @@ -0,0 +1,40 @@ +// +// AnimArmIK.cpp +// +// Created by Angus Antley on 1/9/19. +// Copyright (c) 2019 High Fidelity, Inc. All rights reserved. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "AnimArmIK.h" + +#include + +#include "AnimationLogging.h" +#include "AnimUtil.h" + +AnimArmIK::AnimArmIK(const QString& id, float alpha, bool enabled, float interpDuration, + const QString& baseJointName, const QString& midJointName, + const QString& tipJointName, const glm::vec3& midHingeAxis, + const QString& alphaVar, const QString& enabledVar, + const QString& endEffectorRotationVarVar, const QString& endEffectorPositionVarVar) : + AnimTwoBoneIK(id, alpha, enabled, interpDuration, baseJointName, midJointName, tipJointName, midHingeAxis, alphaVar, enabledVar, endEffectorRotationVarVar, endEffectorPositionVarVar) { + +} + +AnimArmIK::~AnimArmIK() { + +} + +const AnimPoseVec& AnimArmIK::evaluate(const AnimVariantMap& animVars, const AnimContext& context, float dt, AnimVariantMap& triggersOut) { + qCDebug(animation) << "evaluating the arm IK"; + + assert(_children.size() == 1); + if (_children.size() != 1) { + return _poses; + } else { + return _poses; + } +} \ No newline at end of file diff --git a/libraries/animation/src/AnimArmIK.h b/libraries/animation/src/AnimArmIK.h new file mode 100644 index 0000000000..26f79a1b9c --- /dev/null +++ b/libraries/animation/src/AnimArmIK.h @@ -0,0 +1,34 @@ +// +// AnimArmIK.h +// +// Created by Angus Antley on 1/9/19. +// Copyright (c) 2019 High Fidelity, Inc. All rights reserved. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_AnimArmIK_h +#define hifi_AnimArmIK_h + +//#include "AnimNode.h" +#include "AnimTwoBoneIK.h" +//#include "AnimChain.h" + +// Simple two bone IK chain +class AnimArmIK : public AnimTwoBoneIK { +public: + AnimArmIK(const QString& id, float alpha, bool enabled, float interpDuration, + const QString& baseJointName, const QString& midJointName, + const QString& tipJointName, const glm::vec3& midHingeAxis, + const QString& alphaVar, const QString& enabledVar, + const QString& endEffectorRotationVarVar, const QString& endEffectorPositionVarVar); + virtual ~AnimArmIK(); + virtual const AnimPoseVec& evaluate(const AnimVariantMap& animVars, const AnimContext& context, float dt, AnimVariantMap& triggersOut) override; + +protected: + +}; + +#endif // hifi_AnimArmIK_h + From 07a4f49c58196c3f53718bdc6e0e62f80f52af58 Mon Sep 17 00:00:00 2001 From: amantley Date: Tue, 5 Feb 2019 17:21:39 -0800 Subject: [PATCH 049/112] adding the armik nodes into the json --- .../avatar-animation_withSplineIKNode.json | 4 +-- libraries/animation/src/AnimArmIK.cpp | 16 ++++++------ libraries/animation/src/AnimNodeLoader.cpp | 25 +++++++++++++++++++ 3 files changed, 36 insertions(+), 9 deletions(-) diff --git a/interface/resources/avatar/avatar-animation_withSplineIKNode.json b/interface/resources/avatar/avatar-animation_withSplineIKNode.json index b1f198c52c..9fd64860bd 100644 --- a/interface/resources/avatar/avatar-animation_withSplineIKNode.json +++ b/interface/resources/avatar/avatar-animation_withSplineIKNode.json @@ -129,7 +129,7 @@ "children": [ { "id": "rightHandIK", - "type": "twoBoneIK", + "type": "armIK", "data": { "alpha": 1.0, "enabled": false, @@ -159,7 +159,7 @@ "children": [ { "id": "leftHandIK", - "type": "twoBoneIK", + "type": "armIK", "data": { "alpha": 1.0, "enabled": false, diff --git a/libraries/animation/src/AnimArmIK.cpp b/libraries/animation/src/AnimArmIK.cpp index 202e8c8420..ba720f1126 100644 --- a/libraries/animation/src/AnimArmIK.cpp +++ b/libraries/animation/src/AnimArmIK.cpp @@ -20,7 +20,8 @@ AnimArmIK::AnimArmIK(const QString& id, float alpha, bool enabled, float interpD const QString& tipJointName, const glm::vec3& midHingeAxis, const QString& alphaVar, const QString& enabledVar, const QString& endEffectorRotationVarVar, const QString& endEffectorPositionVarVar) : - AnimTwoBoneIK(id, alpha, enabled, interpDuration, baseJointName, midJointName, tipJointName, midHingeAxis, alphaVar, enabledVar, endEffectorRotationVarVar, endEffectorPositionVarVar) { + AnimTwoBoneIK(id, alpha, enabled, interpDuration, baseJointName, midJointName, tipJointName, midHingeAxis, alphaVar, enabledVar, endEffectorRotationVarVar, endEffectorPositionVarVar) +{ } @@ -29,12 +30,13 @@ AnimArmIK::~AnimArmIK() { } const AnimPoseVec& AnimArmIK::evaluate(const AnimVariantMap& animVars, const AnimContext& context, float dt, AnimVariantMap& triggersOut) { + qCDebug(animation) << "evaluating the arm IK"; + _poses = AnimTwoBoneIK::evaluate(animVars, context, dt, triggersOut); + + //assert(_children.size() == 1); + //if (_children.size() != 1) { + // return _poses; + //} - assert(_children.size() == 1); - if (_children.size() != 1) { - return _poses; - } else { - return _poses; - } } \ No newline at end of file diff --git a/libraries/animation/src/AnimNodeLoader.cpp b/libraries/animation/src/AnimNodeLoader.cpp index b637d131f8..707bf7b976 100644 --- a/libraries/animation/src/AnimNodeLoader.cpp +++ b/libraries/animation/src/AnimNodeLoader.cpp @@ -26,6 +26,7 @@ #include "AnimInverseKinematics.h" #include "AnimDefaultPose.h" #include "AnimTwoBoneIK.h" +#include "AnimArmIK.h" #include "AnimSplineIK.h" #include "AnimPoleVectorConstraint.h" @@ -42,6 +43,7 @@ static AnimNode::Pointer loadManipulatorNode(const QJsonObject& jsonObj, const Q static AnimNode::Pointer loadInverseKinematicsNode(const QJsonObject& jsonObj, const QString& id, const QUrl& jsonUrl); static AnimNode::Pointer loadDefaultPoseNode(const QJsonObject& jsonObj, const QString& id, const QUrl& jsonUrl); static AnimNode::Pointer loadTwoBoneIKNode(const QJsonObject& jsonObj, const QString& id, const QUrl& jsonUrl); +static AnimNode::Pointer loadArmIKNode(const QJsonObject& jsonObj, const QString& id, const QUrl& jsonUrl); static AnimNode::Pointer loadSplineIKNode(const QJsonObject& jsonObj, const QString& id, const QUrl& jsonUrl); static AnimNode::Pointer loadPoleVectorConstraintNode(const QJsonObject& jsonObj, const QString& id, const QUrl& jsonUrl); @@ -63,6 +65,7 @@ static const char* animNodeTypeToString(AnimNode::Type type) { case AnimNode::Type::InverseKinematics: return "inverseKinematics"; case AnimNode::Type::DefaultPose: return "defaultPose"; case AnimNode::Type::TwoBoneIK: return "twoBoneIK"; + case AnimNode::Type::ArmIK: return "armIK"; case AnimNode::Type::SplineIK: return "splineIK"; case AnimNode::Type::PoleVectorConstraint: return "poleVectorConstraint"; case AnimNode::Type::NumTypes: return nullptr; @@ -126,6 +129,7 @@ static NodeLoaderFunc animNodeTypeToLoaderFunc(AnimNode::Type type) { case AnimNode::Type::InverseKinematics: return loadInverseKinematicsNode; case AnimNode::Type::DefaultPose: return loadDefaultPoseNode; case AnimNode::Type::TwoBoneIK: return loadTwoBoneIKNode; + case AnimNode::Type::ArmIK: return loadArmIKNode; case AnimNode::Type::SplineIK: return loadSplineIKNode; case AnimNode::Type::PoleVectorConstraint: return loadPoleVectorConstraintNode; case AnimNode::Type::NumTypes: return nullptr; @@ -144,6 +148,7 @@ static NodeProcessFunc animNodeTypeToProcessFunc(AnimNode::Type type) { case AnimNode::Type::InverseKinematics: return processDoNothing; case AnimNode::Type::DefaultPose: return processDoNothing; case AnimNode::Type::TwoBoneIK: return processDoNothing; + case AnimNode::Type::ArmIK: return processDoNothing; case AnimNode::Type::SplineIK: return processDoNothing; case AnimNode::Type::PoleVectorConstraint: return processDoNothing; case AnimNode::Type::NumTypes: return nullptr; @@ -625,6 +630,26 @@ static AnimNode::Pointer loadSplineIKNode(const QJsonObject& jsonObj, const QStr return node; } +static AnimNode::Pointer loadArmIKNode(const QJsonObject& jsonObj, const QString& id, const QUrl& jsonUrl) { + READ_FLOAT(alpha, jsonObj, id, jsonUrl, nullptr); + READ_BOOL(enabled, jsonObj, id, jsonUrl, nullptr); + READ_FLOAT(interpDuration, jsonObj, id, jsonUrl, nullptr); + READ_STRING(baseJointName, jsonObj, id, jsonUrl, nullptr); + READ_STRING(midJointName, jsonObj, id, jsonUrl, nullptr); + READ_STRING(tipJointName, jsonObj, id, jsonUrl, nullptr); + READ_VEC3(midHingeAxis, jsonObj, id, jsonUrl, nullptr); + READ_STRING(alphaVar, jsonObj, id, jsonUrl, nullptr); + READ_STRING(enabledVar, jsonObj, id, jsonUrl, nullptr); + READ_STRING(endEffectorRotationVarVar, jsonObj, id, jsonUrl, nullptr); + READ_STRING(endEffectorPositionVarVar, jsonObj, id, jsonUrl, nullptr); + + auto node = std::make_shared(id, alpha, enabled, interpDuration, + baseJointName, midJointName, tipJointName, midHingeAxis, + alphaVar, enabledVar, + endEffectorRotationVarVar, endEffectorPositionVarVar); + return node; +} + static AnimNode::Pointer loadTwoBoneIKNode(const QJsonObject& jsonObj, const QString& id, const QUrl& jsonUrl) { READ_FLOAT(alpha, jsonObj, id, jsonUrl, nullptr); READ_BOOL(enabled, jsonObj, id, jsonUrl, nullptr); From 9ad20b81296f80a972fc1b3e96c0ee8e9314828f Mon Sep 17 00:00:00 2001 From: amantley Date: Tue, 5 Feb 2019 17:22:00 -0800 Subject: [PATCH 050/112] adding the animcontext to the commit --- libraries/animation/src/AnimContext.h | 1 + 1 file changed, 1 insertion(+) diff --git a/libraries/animation/src/AnimContext.h b/libraries/animation/src/AnimContext.h index e3ab5d9788..2c5b010f1b 100644 --- a/libraries/animation/src/AnimContext.h +++ b/libraries/animation/src/AnimContext.h @@ -28,6 +28,7 @@ enum class AnimNodeType { InverseKinematics, DefaultPose, TwoBoneIK, + ArmIK, SplineIK, PoleVectorConstraint, NumTypes From 22cfcc4ac99c54cce44259d5e40ac39d44856860 Mon Sep 17 00:00:00 2001 From: amantley Date: Tue, 5 Feb 2019 17:25:11 -0800 Subject: [PATCH 051/112] deleted some unity files --- .../unity-avatar-exporter/Assets/Editor.meta | 8 ------- tools/unity-avatar-exporter/Assets/README.txt | 23 ------------------- .../Assets/README.txt.meta | 7 ------ 3 files changed, 38 deletions(-) delete mode 100644 tools/unity-avatar-exporter/Assets/Editor.meta delete mode 100644 tools/unity-avatar-exporter/Assets/README.txt delete mode 100644 tools/unity-avatar-exporter/Assets/README.txt.meta diff --git a/tools/unity-avatar-exporter/Assets/Editor.meta b/tools/unity-avatar-exporter/Assets/Editor.meta deleted file mode 100644 index cf7dcf12dd..0000000000 --- a/tools/unity-avatar-exporter/Assets/Editor.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 02111c50e71dd664da8ad5c6a6eca767 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/tools/unity-avatar-exporter/Assets/README.txt b/tools/unity-avatar-exporter/Assets/README.txt deleted file mode 100644 index f02bc688ae..0000000000 --- a/tools/unity-avatar-exporter/Assets/README.txt +++ /dev/null @@ -1,23 +0,0 @@ -High Fidelity, Inc. -Avatar Exporter -Version 0.1 - -Note: It is recommended to use Unity versions between 2017.4.17f1 and 2018.2.12f1 for this Avatar Exporter. - -To create a new avatar project: -1. Import your .fbx avatar model into your Unity project's Assets by either dragging and dropping the file into the Assets window or by using Assets menu > Import New Assets. -2. Select the .fbx avatar that you imported in step 1 in the Assets window, and in the Rig section of the Inspector window set the Animation Type to Humanoid and choose Apply. -3. With the .fbx avatar still selected in the Assets window, choose High Fidelity menu > Export New Avatar. -4. Select a name for your avatar project (this will be used to create a directory with that name), as well as the target location for your project folder. -5. Once it is exported, your project directory will open in File Explorer. - -To update an existing avatar project: -1. Select the existing .fbx avatar in the Assets window that you would like to re-export. -2. Choose High Fidelity menu > Update Existing Avatar and browse to the .fst file you would like to update. -3. If the .fbx file in your Unity Assets folder is newer than the existing .fbx file in your selected avatar project or vice-versa, you will be prompted if you wish to replace the older file with the newer file before performing the update. -4. Once it is updated, your project directory will open in File Explorer. - -* WARNING * -If you are using any external textures as part of your .fbx model, be sure they are copied into the textures folder that is created in the project folder after exporting a new avatar. - -For further details including troubleshooting tips, see the full documentation at https://docs.highfidelity.com/create-and-explore/avatars/create-avatars/unity-extension diff --git a/tools/unity-avatar-exporter/Assets/README.txt.meta b/tools/unity-avatar-exporter/Assets/README.txt.meta deleted file mode 100644 index 148fd21fdd..0000000000 --- a/tools/unity-avatar-exporter/Assets/README.txt.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: 30b2b6221fd08234eb07c4d6d525d32e -TextScriptImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: From e2c9058f0a36535bc1c5c8a4523b6312cfe45d0d Mon Sep 17 00:00:00 2001 From: amantley Date: Wed, 6 Feb 2019 18:29:33 -0800 Subject: [PATCH 052/112] first try at the new elbow code --- .../src/AnimPoleVectorConstraint.cpp | 58 ++++++++++++++++++- .../animation/src/AnimPoleVectorConstraint.h | 2 + 2 files changed, 59 insertions(+), 1 deletion(-) diff --git a/libraries/animation/src/AnimPoleVectorConstraint.cpp b/libraries/animation/src/AnimPoleVectorConstraint.cpp index f017fe2348..7431b6620b 100644 --- a/libraries/animation/src/AnimPoleVectorConstraint.cpp +++ b/libraries/animation/src/AnimPoleVectorConstraint.cpp @@ -34,6 +34,53 @@ AnimPoleVectorConstraint::~AnimPoleVectorConstraint() { } +float AnimPoleVectorConstraint::findThetaNewWay(const glm::vec3& hand, const glm::vec3& shoulder) const { + // get the default poses for the upper and lower arm + // then use this length to judge how far the arm is away from the shoulder. + // then create weights that make the elbow angle less when the x value is large in either direction. + // make the angle less when z is small. + // lower y with x center lower angle + // lower y with x out higher angle + AnimPose shoulderPose = _skeleton->getAbsoluteDefaultPose(_skeleton->nameToJointIndex("RightShoulder")); + AnimPose handPose = _skeleton->getAbsoluteDefaultPose(_skeleton->nameToJointIndex("RightHand")); + // subtract 10 centimeters from the arm length for some reason actual arm position is clamped to length - 10cm. + float defaultArmLength = glm::length( handPose.trans() - shoulderPose.trans() ) - 10.0f; + qCDebug(animation) << "default arm length " << defaultArmLength; + + // phi_0 is the lowest angle we can have + const float phi_0 = 15.0f; + // biases + const glm::vec3 biases(60.0f, 120.0f, -30.0f); + // weights + const glm::vec3 weights(-70.0f, 60.0f, 210.0f); + glm::vec3 armToHand = hand - shoulder; + qCDebug(animation) << "current arm length " << glm::length(armToHand); + float initial_valuesX = ((fabsf(armToHand[0]) / defaultArmLength) * weights[0]) + biases[0]; + float initial_valuesY = ((armToHand[1] / defaultArmLength) * weights[1]) + biases[1]; + float initial_valuesZ = ((armToHand[2] / defaultArmLength) * weights[2]) + biases[2]; + if (initial_valuesX < 0.0f) { + initial_valuesX = 0.0f; + } + if (initial_valuesY < 0.0f) { + initial_valuesY = 0.0f; + } + if (initial_valuesZ < 0.0f) { + initial_valuesZ = 0.0f; + } + + float theta = initial_valuesX + initial_valuesY + initial_valuesZ; + + if (theta < 13.0f) { + theta = 13.0f; + } + if (theta > 175.0f) { + theta = 175.0f; + } + + qCDebug(animation) << "relative hand" << initial_valuesX << " " << initial_valuesY << " " << initial_valuesZ << "theta value for pole vector is " << theta; + return theta; +} + const AnimPoseVec& AnimPoleVectorConstraint::evaluate(const AnimVariantMap& animVars, const AnimContext& context, float dt, AnimVariantMap& triggersOut) { assert(_children.size() == 1); @@ -121,7 +168,14 @@ const AnimPoseVec& AnimPoleVectorConstraint::evaluate(const AnimVariantMap& anim float sideDot = glm::dot(poleVector, sideVector); float theta = copysignf(1.0f, sideDot) * acosf(dot); - glm::quat deltaRot = glm::angleAxis(theta, unitAxis); + float fred; + if (_skeleton->nameToJointIndex("RightHand") == _tipJointIndex) { + qCDebug(animation) << "theta from the old code " << theta; + fred = findThetaNewWay(tipPose.trans(), basePose.trans()); + } + + //glm::quat deltaRot = glm::angleAxis(theta, unitAxis); + glm::quat deltaRot = glm::angleAxis(((180.0f - fred)/180.0f)*PI, unitAxis); // transform result back into parent relative frame. glm::quat relBaseRot = glm::inverse(baseParentPose.rot()) * deltaRot * basePose.rot(); @@ -208,6 +262,8 @@ const AnimPoseVec& AnimPoleVectorConstraint::evaluate(const AnimVariantMap& anim return _poses; } + + // for AnimDebugDraw rendering const AnimPoseVec& AnimPoleVectorConstraint::getPosesInternal() const { return _poses; diff --git a/libraries/animation/src/AnimPoleVectorConstraint.h b/libraries/animation/src/AnimPoleVectorConstraint.h index 44e22671c1..df8cddec7d 100644 --- a/libraries/animation/src/AnimPoleVectorConstraint.h +++ b/libraries/animation/src/AnimPoleVectorConstraint.h @@ -25,6 +25,8 @@ public: const QString& enabledVar, const QString& poleVectorVar); virtual ~AnimPoleVectorConstraint() override; + float findThetaNewWay(const glm::vec3& hand, const glm::vec3& shoulder) const; + virtual const AnimPoseVec& evaluate(const AnimVariantMap& animVars, const AnimContext& context, float dt, AnimVariantMap& triggersOut) override; protected: From 4d9d597b4f0b4ca04e6031b787be4a563abd7bb9 Mon Sep 17 00:00:00 2001 From: amantley Date: Thu, 7 Feb 2019 11:14:33 -0800 Subject: [PATCH 053/112] tweaked the weights for the arms and negated the theta for the left arm --- .../animation/src/AnimPoleVectorConstraint.cpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/libraries/animation/src/AnimPoleVectorConstraint.cpp b/libraries/animation/src/AnimPoleVectorConstraint.cpp index 7431b6620b..55fbf20691 100644 --- a/libraries/animation/src/AnimPoleVectorConstraint.cpp +++ b/libraries/animation/src/AnimPoleVectorConstraint.cpp @@ -50,13 +50,13 @@ float AnimPoleVectorConstraint::findThetaNewWay(const glm::vec3& hand, const glm // phi_0 is the lowest angle we can have const float phi_0 = 15.0f; // biases - const glm::vec3 biases(60.0f, 120.0f, -30.0f); + const glm::vec3 biases(30.0f, 120.0f, -30.0f); // weights - const glm::vec3 weights(-70.0f, 60.0f, 210.0f); + const glm::vec3 weights(-30.0f, 30.0f, 210.0f); glm::vec3 armToHand = hand - shoulder; qCDebug(animation) << "current arm length " << glm::length(armToHand); float initial_valuesX = ((fabsf(armToHand[0]) / defaultArmLength) * weights[0]) + biases[0]; - float initial_valuesY = ((armToHand[1] / defaultArmLength) * weights[1]) + biases[1]; + float initial_valuesY = ((fabs(armToHand[1]) / defaultArmLength) * weights[1]) + biases[1]; float initial_valuesZ = ((armToHand[2] / defaultArmLength) * weights[2]) + biases[2]; if (initial_valuesX < 0.0f) { initial_valuesX = 0.0f; @@ -169,13 +169,17 @@ const AnimPoseVec& AnimPoleVectorConstraint::evaluate(const AnimVariantMap& anim float theta = copysignf(1.0f, sideDot) * acosf(dot); float fred; - if (_skeleton->nameToJointIndex("RightHand") == _tipJointIndex) { + if ((_skeleton->nameToJointIndex("RightHand") == _tipJointIndex) || (_skeleton->nameToJointIndex("LeftHand") == _tipJointIndex)) { qCDebug(animation) << "theta from the old code " << theta; fred = findThetaNewWay(tipPose.trans(), basePose.trans()); + if (_skeleton->nameToJointIndex("LeftHand") == _tipJointIndex) { + fred = -1.0f * fred; + } + theta = ((180.0f - fred) / 180.0f)*PI; } //glm::quat deltaRot = glm::angleAxis(theta, unitAxis); - glm::quat deltaRot = glm::angleAxis(((180.0f - fred)/180.0f)*PI, unitAxis); + glm::quat deltaRot = glm::angleAxis(theta, unitAxis); // transform result back into parent relative frame. glm::quat relBaseRot = glm::inverse(baseParentPose.rot()) * deltaRot * basePose.rot(); From 02646fb8a9fffe8ba36c05103f29852ad0db26e5 Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Thu, 7 Feb 2019 14:09:53 -0700 Subject: [PATCH 054/112] Working flow as rig param --- libraries/animation/src/Flow.cpp | 714 ++++++++++++++++++ libraries/animation/src/Flow.h | 315 ++++++++ libraries/animation/src/Rig.cpp | 5 +- libraries/animation/src/Rig.h | 1 + .../src/avatars-renderer/Avatar.cpp | 18 + 5 files changed, 1052 insertions(+), 1 deletion(-) create mode 100644 libraries/animation/src/Flow.cpp create mode 100644 libraries/animation/src/Flow.h diff --git a/libraries/animation/src/Flow.cpp b/libraries/animation/src/Flow.cpp new file mode 100644 index 0000000000..a10d413d90 --- /dev/null +++ b/libraries/animation/src/Flow.cpp @@ -0,0 +1,714 @@ +// +// Flow.cpp +// +// Created by Luis Cuenca on 1/21/2019. +// Copyright 2019 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 +// + +#include "Flow.h" +#include "Rig.h" +#include "AnimSkeleton.h" + +FlowCollisionSphere::FlowCollisionSphere(const int& jointIndex, const FlowCollisionSettings& settings) { + _jointIndex = jointIndex; + _radius = _initialRadius = settings._radius; + _offset = _initialOffset = settings._offset; + _entityID = settings._entityID; +} + +FlowCollisionResult FlowCollisionSphere::computeSphereCollision(const glm::vec3& point, float radius) const { + FlowCollisionResult result; + auto centerToJoint = point - _position; + result._distance = glm::length(centerToJoint) - radius; + result._offset = _radius - result._distance; + result._normal = glm::normalize(centerToJoint); + result._radius = _radius; + result._position = _position; + return result; +} + +FlowCollisionResult FlowCollisionSphere::checkSegmentCollision(const glm::vec3& point1, const glm::vec3& point2, const FlowCollisionResult& collisionResult1, const FlowCollisionResult& collisionResult2) { + FlowCollisionResult result; + auto segment = point2 - point1; + auto segmentLength = glm::length(segment); + auto maxDistance = glm::sqrt(glm::pow(collisionResult1._radius, 2) + glm::pow(segmentLength, 2)); + if (collisionResult1._distance < maxDistance && collisionResult2._distance < maxDistance) { + float segmentPercentage = collisionResult1._distance / (collisionResult1._distance + collisionResult2._distance); + glm::vec3 collisionPoint = point1 + segment * segmentPercentage; + glm::vec3 centerToSegment = collisionPoint - _position; + float distance = glm::length(centerToSegment); + if (distance < _radius) { + result._offset = _radius - distance; + result._position = _position; + result._radius = _radius; + result._normal = glm::normalize(centerToSegment); + result._distance = distance; + } + } + return result; +} + +void FlowCollisionSphere::update() { + // TODO + // Fill this +} + +void FlowCollisionSystem::addCollisionSphere(int jointIndex, const FlowCollisionSettings& settings) { + _collisionSpheres.push_back(FlowCollisionSphere(jointIndex, settings)); +}; + +void FlowCollisionSystem::addCollisionShape(int jointIndex, const FlowCollisionSettings& settings) { + auto name = JOINT_COLLISION_PREFIX + jointIndex; + switch (settings._type) { + case FlowCollisionType::CollisionSphere: + addCollisionSphere(jointIndex, settings); + break; + default: + break; + } +}; + +bool FlowCollisionSystem::addCollisionToJoint(int jointIndex) { + if (_collisionSpheres.size() >= COLLISION_SHAPES_LIMIT) { + return false; + } + int collisionIndex = findCollisionWithJoint(jointIndex); + if (collisionIndex == -1) { + addCollisionShape(jointIndex, FlowCollisionSettings()); + return true; + } + else { + return false; + } +}; + +void FlowCollisionSystem::removeCollisionFromJoint(int jointIndex) { + int collisionIndex = findCollisionWithJoint(jointIndex); + if (collisionIndex > -1) { + _collisionSpheres.erase(_collisionSpheres.begin() + collisionIndex); + } +}; + +void FlowCollisionSystem::update() { + for (size_t i = 0; i < _collisionSpheres.size(); i++) { + _collisionSpheres[i].update(); + } +}; + +FlowCollisionResult FlowCollisionSystem::computeCollision(const std::vector collisions) { + FlowCollisionResult result; + if (collisions.size() > 1) { + for (size_t i = 0; i < collisions.size(); i++) { + result._offset += collisions[i]._offset; + result._normal = result._normal + collisions[i]._normal * collisions[i]._distance; + result._position = result._position + collisions[i]._position; + result._radius += collisions[i]._radius; + result._distance += collisions[i]._distance; + } + result._offset = result._offset / collisions.size(); + result._radius = 0.5f * glm::length(result._normal); + result._normal = glm::normalize(result._normal); + result._position = result._position / (float)collisions.size(); + result._distance = result._distance / collisions.size(); + } + else if (collisions.size() == 1) { + result = collisions[0]; + } + result._count = (int)collisions.size(); + return result; +}; + +void FlowCollisionSystem::setScale(float scale) { + _scale = scale; + for (size_t j = 0; j < _collisionSpheres.size(); j++) { + _collisionSpheres[j]._radius = _collisionSpheres[j]._initialRadius * scale; + _collisionSpheres[j]._offset = _collisionSpheres[j]._initialOffset * scale; + } +}; + +std::vector FlowCollisionSystem::checkFlowThreadCollisions(FlowThread* flowThread, bool checkSegments) { + std::vector> FlowThreadResults; + FlowThreadResults.resize(flowThread->_joints.size()); + for (size_t j = 0; j < _collisionSpheres.size(); j++) { + FlowCollisionSphere &sphere = _collisionSpheres[j]; + FlowCollisionResult rootCollision = sphere.computeSphereCollision(flowThread->_positions[0], flowThread->_radius); + std::vector collisionData = { rootCollision }; + bool tooFar = rootCollision._distance >(flowThread->_length + rootCollision._radius); + FlowCollisionResult nextCollision; + if (!tooFar) { + if (checkSegments) { + for (size_t i = 1; i < flowThread->_joints.size(); i++) { + auto prevCollision = collisionData[i - 1]; + nextCollision = _collisionSpheres[j].computeSphereCollision(flowThread->_positions[i], flowThread->_radius); + collisionData.push_back(nextCollision); + if (prevCollision._offset > 0.0f) { + if (i == 1) { + FlowThreadResults[i - 1].push_back(prevCollision); + } + } + else if (nextCollision._offset > 0.0f) { + FlowThreadResults[i].push_back(nextCollision); + } + else { + FlowCollisionResult segmentCollision = _collisionSpheres[j].checkSegmentCollision(flowThread->_positions[i - 1], flowThread->_positions[i], prevCollision, nextCollision); + if (segmentCollision._offset > 0) { + FlowThreadResults[i - 1].push_back(segmentCollision); + FlowThreadResults[i].push_back(segmentCollision); + } + } + } + } + else { + if (rootCollision._offset > 0.0f) { + FlowThreadResults[0].push_back(rootCollision); + } + for (size_t i = 1; i < flowThread->_joints.size(); i++) { + nextCollision = _collisionSpheres[j].computeSphereCollision(flowThread->_positions[i], flowThread->_radius); + if (nextCollision._offset > 0.0f) { + FlowThreadResults[i].push_back(nextCollision); + } + } + } + } + } + + std::vector results; + for (size_t i = 0; i < flowThread->_joints.size(); i++) { + results.push_back(computeCollision(FlowThreadResults[i])); + } + return results; +}; + +int FlowCollisionSystem::findCollisionWithJoint(int jointIndex) { + for (size_t i = 0; i < _collisionSpheres.size(); i++) { + if (_collisionSpheres[i]._jointIndex == jointIndex) { + return (int)i; + } + } + return -1; +}; + +void FlowCollisionSystem::modifyCollisionRadius(int jointIndex, float radius) { + int collisionIndex = findCollisionWithJoint(jointIndex); + if (collisionIndex > -1) { + _collisionSpheres[collisionIndex]._initialRadius = radius; + _collisionSpheres[collisionIndex]._radius = _scale * radius; + } +}; + +void FlowCollisionSystem::modifyCollisionYOffset(int jointIndex, float offset) { + int collisionIndex = findCollisionWithJoint(jointIndex); + if (collisionIndex > -1) { + auto currentOffset = _collisionSpheres[collisionIndex]._offset; + _collisionSpheres[collisionIndex]._initialOffset = glm::vec3(currentOffset.x, offset, currentOffset.z); + _collisionSpheres[collisionIndex]._offset = _collisionSpheres[collisionIndex]._initialOffset * _scale; + } +}; + +void FlowCollisionSystem::modifyCollisionOffset(int jointIndex, const glm::vec3& offset) { + int collisionIndex = findCollisionWithJoint(jointIndex); + if (collisionIndex > -1) { + _collisionSpheres[collisionIndex]._initialOffset = offset; + _collisionSpheres[collisionIndex]._offset = _collisionSpheres[collisionIndex]._initialOffset * _scale; + } +}; + +void FlowNode::update(const glm::vec3& accelerationOffset) { + _acceleration = glm::vec3(0.0f, _settings._gravity, 0.0f); + _previousVelocity = _currentVelocity; + _currentVelocity = _currentPosition - _previousPosition; + _previousPosition = _currentPosition; + if (!_anchored) { + // Add inertia + auto deltaVelocity = _previousVelocity - _currentVelocity; + auto centrifugeVector = glm::length(deltaVelocity) != 0.0f ? glm::normalize(deltaVelocity) : glm::vec3(); + _acceleration = _acceleration + centrifugeVector * _settings._inertia * glm::length(_currentVelocity); + + // Add offset + _acceleration += accelerationOffset; + // Calculate new position + _currentPosition = (_currentPosition + _currentVelocity * _settings._damping) + + (_acceleration * glm::pow(_settings._delta * _scale, 2)); + } + else { + _acceleration = glm::vec3(0.0f); + _currentVelocity = glm::vec3(0.0f); + } +}; + + +void FlowNode::solve(const glm::vec3& constrainPoint, float maxDistance, const FlowCollisionResult& collision) { + solveConstraints(constrainPoint, maxDistance); + solveCollisions(collision); +}; + +void FlowNode::solveConstraints(const glm::vec3& constrainPoint, float maxDistance) { + glm::vec3 constrainVector = _currentPosition - constrainPoint; + float difference = maxDistance / glm::length(constrainVector); + _currentPosition = difference < 1.0 ? constrainPoint + constrainVector * difference : _currentPosition; +}; + +void FlowNode::solveCollisions(const FlowCollisionResult& collision) { + _colliding = collision._offset > 0.0f; + _collision = collision; + if (_colliding) { + _currentPosition = _currentPosition + collision._normal * collision._offset; + _previousCollision = collision; + } + else { + _previousCollision = FlowCollisionResult(); + } +}; + +void FlowNode::apply(const QString& name, bool forceRendering) { + // TODO + // Render here ?? + /* + jointDebug.setDebugSphere(name, self.currentPosition, 2 * self.radius, { red: self.collision && self.collision.collisionCount > 1 ? 0 : 255, + green : self.colliding ? 0 : 255, + blue : 0 }, forceRendering); + */ +}; + +FlowJoint::FlowJoint(int jointIndex, int parentIndex, int childIndex, const QString& name, const QString& group, float scale, const FlowPhysicsSettings& settings) { + _index = jointIndex; + _name = name; + _group = group; + _scale = scale; + _childIndex = childIndex; + _parentIndex = parentIndex; + _node = FlowNode(glm::vec3(), settings); +}; + +void FlowJoint::setInitialData(const glm::vec3& initialPosition, const glm::vec3& initialTranslation, const glm::quat& initialRotation, const glm::vec3& parentPosition) { + _initialPosition = initialPosition; + _node._initialPosition = initialPosition; + _node._previousPosition = initialPosition; + _node._currentPosition = initialPosition; + _initialTranslation = initialTranslation; + _initialRotation = initialRotation; + _translationDirection = glm::normalize(_initialTranslation); + _parentPosition = parentPosition; + _length = glm::length(_initialPosition - parentPosition); + _originalLength = _length / _scale; +} + +void FlowJoint::setUpdatedData(const glm::vec3& updatedPosition, const glm::vec3& updatedTranslation, const glm::quat& updatedRotation, const glm::vec3& parentPosition, const glm::quat& parentWorldRotation) { + _updatedPosition = updatedPosition; + _updatedRotation = updatedRotation; + _updatedTranslation = updatedTranslation; + _parentPosition = parentPosition; + _parentWorldRotation = parentWorldRotation; +} + +void FlowJoint::setRecoveryPosition(const glm::vec3& recoveryPosition) { + _recoveryPosition = recoveryPosition; + _applyRecovery = true; +} + +void FlowJoint::update() { + glm::vec3 accelerationOffset = glm::vec3(0.0f); + if (_node._settings._stiffness > 0.0f) { + glm::vec3 recoveryVector = _recoveryPosition - _node._currentPosition; + accelerationOffset = recoveryVector * glm::pow(_node._settings._stiffness, 3); + } + _node.update(accelerationOffset); + if (_node._anchored) { + if (!_isDummy) { + _node._currentPosition = _updatedPosition; + } else { + _node._currentPosition = _parentPosition; + } + } +}; + +void FlowJoint::solve(const FlowCollisionResult& collision) { + _node.solve(_parentPosition, _length, collision); +}; + +FlowDummyJoint::FlowDummyJoint(const glm::vec3& initialPosition, int index, int parentIndex, int childIndex, float scale, FlowPhysicsSettings settings) : + FlowJoint(index, parentIndex, childIndex, DUMMY_KEYWORD + "_" + index, DUMMY_KEYWORD, scale, settings) { + _isDummy = true; + _initialPosition = initialPosition; + _node = FlowNode(_initialPosition, settings); + _length = DUMMY_JOINT_DISTANCE; +} + + +FlowThread::FlowThread(int rootIndex, std::map* joints) { + _jointsPointer = joints; + computeFlowThread(rootIndex); +} + +void FlowThread::resetLength() { + _length = 0.0f; + for (size_t i = 1; i < _joints.size(); i++) { + int index = _joints[i]; + _length += (*_jointsPointer)[index]._length; + } +} + +void FlowThread::computeFlowThread(int rootIndex) { + int parentIndex = rootIndex; + if (_jointsPointer->size() == 0) { + return; + } + int childIndex = (*_jointsPointer)[parentIndex]._childIndex; + std::vector indexes = { parentIndex }; + for (size_t i = 0; i < _jointsPointer->size(); i++) { + if (childIndex > -1) { + indexes.push_back(childIndex); + childIndex = (*_jointsPointer)[childIndex]._childIndex; + } else { + break; + } + } + for (size_t i = 0; i < indexes.size(); i++) { + int index = indexes[i]; + _joints.push_back(index); + if (i > 0) { + _length += (*_jointsPointer)[index]._length; + } + } +}; + +void FlowThread::computeRecovery() { + int parentIndex = _joints[0]; + auto parentJoint = (*_jointsPointer)[parentIndex]; + (*_jointsPointer)[parentIndex]._recoveryPosition = parentJoint._recoveryPosition = parentJoint._node._currentPosition; + glm::quat parentRotation = parentJoint._parentWorldRotation * parentJoint._initialRotation; + for (size_t i = 1; i < _joints.size(); i++) { + auto joint = (*_jointsPointer)[_joints[i]]; + glm::quat rotation = i == 1 ? parentRotation : rotation * parentJoint._initialRotation; + (*_jointsPointer)[_joints[i]]._recoveryPosition = joint._recoveryPosition = parentJoint._recoveryPosition + (rotation * (joint._initialTranslation * 0.01f)); + parentJoint = joint; + } +}; + +void FlowThread::update() { + if (getActive()) { + _positions.clear(); + _radius = (*_jointsPointer)[_joints[0]]._node._settings._radius; + computeRecovery(); + for (size_t i = 0; i < _joints.size(); i++) { + auto &joint = (*_jointsPointer)[_joints[i]]; + joint.update(); + _positions.push_back(joint._node._currentPosition); + } + } +}; + +void FlowThread::solve(bool useCollisions, FlowCollisionSystem& collisionSystem) { + if (getActive()) { + if (useCollisions) { + auto bodyCollisions = collisionSystem.checkFlowThreadCollisions(this, false); + int handTouchedJoint = -1; + for (size_t i = 0; i < _joints.size(); i++) { + int index = _joints[i]; + if (bodyCollisions[i]._offset > 0.0f) { + (*_jointsPointer)[index].solve(bodyCollisions[i]); + } else { + (*_jointsPointer)[index].solve(FlowCollisionResult()); + } + } + } else { + for (size_t i = 0; i < _joints.size(); i++) { + int index = _joints[i]; + (*_jointsPointer)[index].solve(FlowCollisionResult()); + } + } + } +}; + +void FlowThread::computeJointRotations() { + + auto pos0 = _rootFramePositions[0]; + auto pos1 = _rootFramePositions[1]; + + auto joint0 = (*_jointsPointer)[_joints[0]]; + auto joint1 = (*_jointsPointer)[_joints[1]]; + + auto initial_pos1 = pos0 + (joint0._initialRotation * (joint1._initialTranslation * 0.01f)); + + auto vec0 = initial_pos1 - pos0; + auto vec1 = pos1 - pos0; + + auto delta = rotationBetween(vec0, vec1); + + joint0._currentRotation = (*_jointsPointer)[_joints[0]]._currentRotation = delta * joint0._initialRotation; + + for (size_t i = 1; i < _joints.size() - 1; i++) { + auto nextJoint = (*_jointsPointer)[_joints[i + 1]]; + for (size_t j = i; j < _joints.size(); j++) { + _rootFramePositions[j] = glm::inverse(joint0._currentRotation) * _rootFramePositions[j] - (joint0._initialTranslation * 0.01f); + } + pos0 = _rootFramePositions[i]; + pos1 = _rootFramePositions[i + 1]; + initial_pos1 = pos0 + joint1._initialRotation * (nextJoint._initialTranslation * 0.01f); + + vec0 = initial_pos1 - pos0; + vec1 = pos1 - pos0; + + delta = rotationBetween(vec0, vec1); + + joint1._currentRotation = (*_jointsPointer)[joint1._index]._currentRotation = delta * joint1._initialRotation; + joint0 = joint1; + joint1 = nextJoint; + } +}; + +void FlowThread::apply() { + if (!getActive()) { + return; + } + computeJointRotations(); +}; + +bool FlowThread::getActive() { + return (*_jointsPointer)[_joints[0]]._node._active; +}; + +void Flow::setRig(Rig* rig) { + _rig = rig; +}; + +void Flow::calculateConstraints() { + cleanUp(); + if (!_rig) { + return; + } + int rightHandIndex = -1; + auto flowPrefix = FLOW_JOINT_PREFIX.toUpper(); + auto simPrefix = SIM_JOINT_PREFIX.toUpper(); + auto skeleton = _rig->getAnimSkeleton(); + if (skeleton) { + for (int i = 0; i < skeleton->getNumJoints(); i++) { + auto name = skeleton->getJointName(i); + if (name == "RightHand") { + rightHandIndex = i; + } + auto parentIndex = skeleton->getParentIndex(i); + if (parentIndex == -1) { + continue; + } + auto jointChildren = skeleton->getChildrenOfJoint(i); + // auto childIndex = jointChildren.size() > 0 ? jointChildren[0] : -1; + auto group = QStringRef(&name, 0, 3).toString().toUpper(); + auto split = name.split("_"); + bool isSimJoint = (group == simPrefix); + bool isFlowJoint = split.size() > 2 && split[0].toUpper() == flowPrefix; + if (isFlowJoint || isSimJoint) { + group = ""; + if (isSimJoint) { + qDebug() << "FLOW is sim: " << name; + for (size_t j = 1; j < name.size() - 1; j++) { + bool toFloatSuccess; + auto subname = (QStringRef(&name, (int)(name.size() - j), 1)).toString().toFloat(&toFloatSuccess); + if (!toFloatSuccess && (name.size() - j) > simPrefix.size()) { + group = QStringRef(&name, simPrefix.size(), (int)(name.size() - j + 1)).toString(); + break; + } + } + if (group.isEmpty()) { + group = QStringRef(&name, simPrefix.size(), name.size() - 1).toString(); + } + } else { + group = split[1]; + } + if (!group.isEmpty()) { + _flowJointKeywords.push_back(group); + FlowPhysicsSettings jointSettings; + if (PRESET_FLOW_DATA.find(group) != PRESET_FLOW_DATA.end()) { + jointSettings = PRESET_FLOW_DATA.at(group); + } else { + jointSettings = DEFAULT_JOINT_SETTINGS; + } + if (_flowJointData.find(i) == _flowJointData.end()) { + auto flowJoint = FlowJoint(i, parentIndex, -1, name, group, _scale, jointSettings); + _flowJointData.insert(std::pair(i, flowJoint)); + } + } + } else { + if (PRESET_COLLISION_DATA.find(name) != PRESET_COLLISION_DATA.end()) { + _collisionSystem.addCollisionShape(i, PRESET_COLLISION_DATA.at(name)); + } + } + if (isFlowJoint || isSimJoint) { + auto jointInfo = FlowJointInfo(i, parentIndex, -1, name); + _flowJointInfos.push_back(jointInfo); + } + } + } + + for (auto &jointData : _flowJointData) { + int jointIndex = jointData.first; + glm::vec3 jointPosition, parentPosition, jointTranslation; + glm::quat jointRotation; + _rig->getJointPositionInWorldFrame(jointIndex, jointPosition, _entityPosition, _entityRotation); + _rig->getJointPositionInWorldFrame(jointData.second._parentIndex, parentPosition, _entityPosition, _entityRotation); + _rig->getJointTranslation(jointIndex, jointTranslation); + _rig->getJointRotation(jointIndex, jointRotation); + + jointData.second.setInitialData(jointPosition, jointTranslation, jointRotation, parentPosition); + } + + std::vector roots; + + for (auto& itr = _flowJointData.begin(); itr != _flowJointData.end(); itr++) { + if (_flowJointData.find(itr->second._parentIndex) == _flowJointData.end()) { + itr->second._node._anchored = true; + roots.push_back(itr->first); + } else { + _flowJointData[itr->second._parentIndex]._childIndex = itr->first; + } + } + + for (size_t i = 0; i < roots.size(); i++) { + FlowThread thread = FlowThread(roots[i], &_flowJointData); + // add threads with at least 2 joints + if (thread._joints.size() > 0) { + if (thread._joints.size() == 1) { + int jointIndex = roots[i]; + auto joint = _flowJointData[jointIndex]; + auto jointPosition = joint._updatedPosition; + auto newSettings = FlowPhysicsSettings(joint._node._settings); + newSettings._stiffness = ISOLATED_JOINT_STIFFNESS; + int extraIndex = (int)_flowJointData.size(); + auto newJoint = FlowDummyJoint(jointPosition, extraIndex, jointIndex, -1, _scale, newSettings); + newJoint._isDummy = false; + newJoint._length = ISOLATED_JOINT_LENGTH; + newJoint._childIndex = extraIndex; + newJoint._group = _flowJointData[jointIndex]._group; + thread = FlowThread(jointIndex, &_flowJointData); + } + _jointThreads.push_back(thread); + } + } + + if (_jointThreads.size() == 0) { + _rig->clearJointStates(); + } + + + if (SHOW_DUMMY_JOINTS && rightHandIndex > -1) { + int jointCount = (int)_flowJointData.size(); + int extraIndex = (int)_flowJointData.size(); + glm::vec3 rightHandPosition; + _rig->getJointPositionInWorldFrame(rightHandIndex, rightHandPosition, _entityPosition, _entityRotation); + int parentIndex = rightHandIndex; + for (int i = 0; i < DUMMY_JOINT_COUNT; i++) { + int childIndex = (i == (DUMMY_JOINT_COUNT - 1)) ? -1 : extraIndex + 1; + auto newJoint = FlowDummyJoint(rightHandPosition, extraIndex, parentIndex, childIndex, _scale, DEFAULT_JOINT_SETTINGS); + _flowJointData.insert(std::pair(extraIndex, newJoint)); + parentIndex = extraIndex; + extraIndex++; + } + _flowJointData[jointCount]._node._anchored = true; + + auto extraThread = FlowThread(jointCount, &_flowJointData); + _jointThreads.push_back(extraThread); + } + _initialized = _jointThreads.size() > 0; +} + +void Flow::cleanUp() { + _flowJointData.clear(); + _jointThreads.clear(); + _flowJointKeywords.clear(); + _flowJointInfos.clear(); + } + +void Flow::setTransform(float scale, const glm::vec3& position, const glm::quat& rotation) { + _scale = scale; + for (auto &joint : _flowJointData) { + joint.second._scale = scale; + joint.second._node._scale = scale; + } + _entityPosition = position; + _entityRotation = rotation; + _active = true; +} + +void Flow::update() { + _timer.start(); + if (_initialized && _active) { + updateJoints(); + if (USE_COLLISIONS) { + _collisionSystem.update(); + } + int count = 0; + for (auto &thread : _jointThreads) { + thread.update(); + thread.solve(USE_COLLISIONS, _collisionSystem); + if (!updateRootFramePositions(count++)) { + return; + } + thread.apply(); + } + setJoints(); + } + _elapsedTime = ((1.0 - _tau) * _elapsedTime + _tau * _timer.nsecsElapsed()); + _deltaTime += _elapsedTime; + if (_deltaTime > _deltaTimeLimit) { + qDebug() << "Flow C++ update" << _elapsedTime; + _deltaTime = 0.0; + } + +} + +bool Flow::worldToJointPoint(const glm::vec3& position, const int jointIndex, glm::vec3& jointSpacePosition) const { + glm::vec3 jointPos; + glm::quat jointRot; + if (_rig->getJointPositionInWorldFrame(jointIndex, jointPos, _entityPosition, _entityRotation) && _rig->getJointRotationInWorldFrame(jointIndex, jointRot, _entityRotation)) { + glm::vec3 modelOffset = position - jointPos; + jointSpacePosition = glm::inverse(jointRot) * modelOffset; + return true; + } + return false; +} + +bool Flow::updateRootFramePositions(int threadIndex) { + auto &joints = _jointThreads[threadIndex]._joints; + int rootIndex = _flowJointData[joints[0]]._parentIndex; + _jointThreads[threadIndex]._rootFramePositions.clear(); + for (size_t j = 0; j < joints.size(); j++) { + glm::vec3 jointPos; + if (worldToJointPoint(_flowJointData[joints[j]]._node._currentPosition, rootIndex, jointPos)) { + _jointThreads[threadIndex]._rootFramePositions.push_back(jointPos); + } else { + return false; + } + } + return true; +} + +void Flow::updateJoints() { + for (auto &jointData : _flowJointData) { + int jointIndex = jointData.first; + glm::vec3 jointPosition, parentPosition, jointTranslation; + glm::quat jointRotation, parentWorldRotation; + _rig->getJointPositionInWorldFrame(jointIndex, jointPosition, _entityPosition, _entityRotation); + _rig->getJointPositionInWorldFrame(jointData.second._parentIndex, parentPosition, _entityPosition, _entityRotation); + _rig->getJointTranslation(jointIndex, jointTranslation); + _rig->getJointRotation(jointIndex, jointRotation); + _rig->getJointRotationInWorldFrame(jointData.second._parentIndex, parentWorldRotation, _entityRotation); + jointData.second.setUpdatedData(jointPosition, jointTranslation, jointRotation, parentPosition, parentWorldRotation); + } + auto &collisions = _collisionSystem.getCollisions(); + for (auto &collision : collisions) { + _rig->getJointPositionInWorldFrame(collision._jointIndex, collision._position, _entityPosition, _entityRotation); + } +} + +void Flow::setJoints() { + for (auto &thread : _jointThreads) { + auto &joints = thread._joints; + for (int jointIndex : joints) { + auto &joint = _flowJointData[jointIndex]; + _rig->setJointRotation(jointIndex, true, joint._currentRotation, 2.0f); + } + } +} diff --git a/libraries/animation/src/Flow.h b/libraries/animation/src/Flow.h new file mode 100644 index 0000000000..c93cf91673 --- /dev/null +++ b/libraries/animation/src/Flow.h @@ -0,0 +1,315 @@ +// +// Flow.h +// +// Created by Luis Cuenca on 1/21/2019. +// Copyright 2019 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 +// + +#ifndef hifi_Flow_h +#define hifi_Flow_h + +#include +#include +#include +#include +#include +#include +#include + +class Rig; +class AnimSkeleton; + +const bool SHOW_AVATAR = true; +const bool SHOW_DEBUG_SHAPES = false; +const bool SHOW_SOLID_SHAPES = false; +const bool SHOW_DUMMY_JOINTS = false; +const bool USE_COLLISIONS = true; + +const int LEFT_HAND = 0; +const int RIGHT_HAND = 1; + +const float HAPTIC_TOUCH_STRENGTH = 0.25f; +const float HAPTIC_TOUCH_DURATION = 10.0f; +const float HAPTIC_SLOPE = 0.18f; +const float HAPTIC_THRESHOLD = 40.0f; + +const QString FLOW_JOINT_PREFIX = "flow"; +const QString SIM_JOINT_PREFIX = "sim"; + +const QString JOINT_COLLISION_PREFIX = "joint_"; +const QString HAND_COLLISION_PREFIX = "hand_"; +const float HAND_COLLISION_RADIUS = 0.03f; +const float HAND_TOUCHING_DISTANCE = 2.0f; + +const int COLLISION_SHAPES_LIMIT = 4; + +const QString DUMMY_KEYWORD = "Extra"; +const int DUMMY_JOINT_COUNT = 8; +const float DUMMY_JOINT_DISTANCE = 0.05f; + +const float ISOLATED_JOINT_STIFFNESS = 0.0f; +const float ISOLATED_JOINT_LENGTH = 0.05f; + +const float DEFAULT_STIFFNESS = 0.8f; +const float DEFAULT_GRAVITY = -0.0096f; +const float DEFAULT_DAMPING = 0.85f; +const float DEFAULT_INERTIA = 0.8f; +const float DEFAULT_DELTA = 0.55f; +const float DEFAULT_RADIUS = 0.01f; + +struct FlowPhysicsSettings { + FlowPhysicsSettings() {}; + FlowPhysicsSettings(bool active, float stiffness, float gravity, float damping, float inertia, float delta, float radius) { + _active = active; + _stiffness = stiffness; + _gravity = gravity; + _damping = damping; + _inertia = inertia; + _delta = delta; + _radius = radius; + } + bool _active{ true }; + float _stiffness{ 0.0f }; + float _gravity{ DEFAULT_GRAVITY }; + float _damping{ DEFAULT_DAMPING }; + float _inertia{ DEFAULT_INERTIA }; + float _delta{ DEFAULT_DELTA }; + float _radius{ DEFAULT_RADIUS }; +}; + +enum FlowCollisionType { + CollisionSphere = 0 +}; + +struct FlowCollisionSettings { + FlowCollisionSettings() {}; + FlowCollisionSettings(const QUuid& id, const FlowCollisionType& type, const glm::vec3& offset, float radius) { + _entityID = id; + _type = type; + _offset = offset; + _radius = radius; + }; + QUuid _entityID; + FlowCollisionType _type { FlowCollisionType::CollisionSphere }; + float _radius { 0.05f }; + glm::vec3 _offset; +}; + +const FlowPhysicsSettings DEFAULT_JOINT_SETTINGS; + +const std::map PRESET_FLOW_DATA = { {"hair", FlowPhysicsSettings()}, + {"skirt", FlowPhysicsSettings(true, 1.0f, DEFAULT_GRAVITY, 0.65f, 0.8f, 0.45f, 0.01f)}, + {"breast", FlowPhysicsSettings(true, 1.0f, DEFAULT_GRAVITY, 0.65f, 0.8f, 0.45f, 0.01f)} }; + +const std::map PRESET_COLLISION_DATA = { + { "Head", FlowCollisionSettings(QUuid(), FlowCollisionType::CollisionSphere, glm::vec3(0.0f, 0.06f, 0.0f), 0.08f)}, + { "LeftArm", FlowCollisionSettings(QUuid(), FlowCollisionType::CollisionSphere, glm::vec3(0.0f, 0.02f, 0.0f), 0.05f) }, + { "Head", FlowCollisionSettings(QUuid(), FlowCollisionType::CollisionSphere, glm::vec3(0.0f, 0.04f, 0.0f), 0.0f) } +}; + +const std::vector HAND_COLLISION_JOINTS = { "RightHandMiddle1", "RightHandThumb3", "LeftHandMiddle1", "LeftHandThumb3", "RightHandMiddle3", "LeftHandMiddle3" }; + +struct FlowJointInfo { + FlowJointInfo() {}; + FlowJointInfo(int index, int parentIndex, int childIndex, const QString& name) { + _index = index; + _parentIndex = parentIndex; + _childIndex = childIndex; + _name = name; + } + int _index { -1 }; + QString _name; + int _parentIndex { -1 }; + int _childIndex { -1 }; +}; + +struct FlowCollisionResult { + int _count { 0 }; + float _offset { 0.0f }; + glm::vec3 _position; + float _radius { 0.0f }; + glm::vec3 _normal; + float _distance { 0.0f }; +}; + +class FlowCollisionSphere { +public: + FlowCollisionSphere() {}; + FlowCollisionSphere(const int& jointIndex, const FlowCollisionSettings& settings); + void setPosition(const glm::vec3& position) { _position = position; } + FlowCollisionResult computeSphereCollision(const glm::vec3& point, float radius) const; + FlowCollisionResult checkSegmentCollision(const glm::vec3& point1, const glm::vec3& point2, const FlowCollisionResult& collisionResult1, const FlowCollisionResult& collisionResult2); + void update(); + + QUuid _entityID; + int _jointIndex { -1 }; + float _radius { 0.0f }; + float _initialRadius{ 0.0f }; + glm::vec3 _offset; + glm::vec3 _initialOffset; + glm::vec3 _position; +}; + +class FlowThread; + +class FlowCollisionSystem { +public: + FlowCollisionSystem() {}; + void addCollisionSphere(int jointIndex, const FlowCollisionSettings& settings); + void addCollisionShape(int jointIndex, const FlowCollisionSettings& settings); + bool addCollisionToJoint(int jointIndex); + void removeCollisionFromJoint(int jointIndex); + void update(); + FlowCollisionResult computeCollision(const std::vector collisions); + void setScale(float scale); + + std::vector checkFlowThreadCollisions(FlowThread* flowThread, bool checkSegments); + + int findCollisionWithJoint(int jointIndex); + void modifyCollisionRadius(int jointIndex, float radius); + void modifyCollisionYOffset(int jointIndex, float offset); + void modifyCollisionOffset(int jointIndex, const glm::vec3& offset); + + std::vector& getCollisions() { return _collisionSpheres; }; +private: + std::vector _collisionSpheres; + float _scale{ 1.0f }; +}; + +class FlowNode { +public: + FlowNode() {}; + FlowNode(const glm::vec3& initialPosition, FlowPhysicsSettings settings) : + _initialPosition(initialPosition), _previousPosition(initialPosition), _currentPosition(initialPosition){}; + + FlowPhysicsSettings _settings; + glm::vec3 _initialPosition; + glm::vec3 _previousPosition; + glm::vec3 _currentPosition; + + glm::vec3 _currentVelocity; + glm::vec3 _previousVelocity; + glm::vec3 _acceleration; + + FlowCollisionResult _collision; + FlowCollisionResult _previousCollision; + + float _initialRadius { 0.0f }; + float _scale{ 1.0f }; + + bool _anchored { false }; + bool _colliding { false }; + bool _active { true }; + + void update(const glm::vec3& accelerationOffset); + void solve(const glm::vec3& constrainPoint, float maxDistance, const FlowCollisionResult& collision); + void solveConstraints(const glm::vec3& constrainPoint, float maxDistance); + void solveCollisions(const FlowCollisionResult& collision); + void apply(const QString& name, bool forceRendering); +}; + +class FlowJoint { +public: + FlowJoint() {}; + FlowJoint(int jointIndex, int parentIndex, int childIndex, const QString& name, const QString& group, float scale, const FlowPhysicsSettings& settings); + void setInitialData(const glm::vec3& initialPosition, const glm::vec3& initialTranslation, const glm::quat& initialRotation, const glm::vec3& parentPosition); + void setUpdatedData(const glm::vec3& updatedPosition, const glm::vec3& updatedTranslation, const glm::quat& updatedRotation, const glm::vec3& parentPosition, const glm::quat& parentWorldRotation); + void setRecoveryPosition(const glm::vec3& recoveryPosition); + void update(); + void solve(const FlowCollisionResult& collision); + + int _index{ -1 }; + int _parentIndex{ -1 }; + int _childIndex{ -1 }; + QString _name; + QString _group; + bool _isDummy{ false }; + glm::vec3 _initialPosition; + glm::vec3 _initialTranslation; + glm::quat _initialRotation; + + glm::vec3 _updatedPosition; + glm::vec3 _updatedTranslation; + glm::quat _updatedRotation; + + glm::quat _currentRotation; + glm::vec3 _recoveryPosition; + + glm::vec3 _parentPosition; + glm::quat _parentWorldRotation; + + FlowNode _node; + glm::vec3 _translationDirection; + float _scale { 1.0f }; + float _length { 0.0f }; + float _originalLength { 0.0f }; + bool _applyRecovery { false }; +}; + +class FlowDummyJoint : public FlowJoint { +public: + FlowDummyJoint(const glm::vec3& initialPosition, int index, int parentIndex, int childIndex, float scale, FlowPhysicsSettings settings); +}; + + +class FlowThread { +public: + FlowThread() {}; + FlowThread(int rootIndex, std::map* joints); + + void resetLength(); + void computeFlowThread(int rootIndex); + void computeRecovery(); + void update(); + void solve(bool useCollisions, FlowCollisionSystem& collisionSystem); + void computeJointRotations(); + void apply(); + bool getActive(); + void setRootFramePositions(const std::vector& rootFramePositions) { _rootFramePositions = rootFramePositions; }; + + std::vector _joints; + std::vector _positions; + float _radius{ 0.0f }; + float _length{ 0.0f }; + std::map* _jointsPointer; + std::vector _rootFramePositions; + +}; + +class Flow { +public: + Flow() {}; + void setRig(Rig* rig); + void calculateConstraints(); + void update(); + void setTransform(float scale, const glm::vec3& position, const glm::quat& rotation); + const std::map& getJoints() const { return _flowJointData; } + const std::vector& getThreads() const { return _jointThreads; } +private: + void setJoints(); + void cleanUp(); + void updateJoints(); + bool updateRootFramePositions(int threadIndex); + bool worldToJointPoint(const glm::vec3& position, const int jointIndex, glm::vec3& jointSpacePosition) const; + Rig* _rig; + float _scale { 1.0f }; + glm::vec3 _entityPosition; + glm::quat _entityRotation; + std::map _flowJointData; + std::vector _jointThreads; + std::vector _flowJointKeywords; + std::vector _flowJointInfos; + FlowCollisionSystem _collisionSystem; + bool _initialized { false }; + bool _active { false }; + int _deltaTime{ 0 }; + int _deltaTimeLimit{ 4000 }; + int _elapsedTime{ 0 }; + float _tau = 0.1f; + QElapsedTimer _timer; +}; + +#endif // hifi_Flow_h diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index 8a05bdd018..5042c00be6 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -748,7 +748,7 @@ void Rig::computeMotionAnimationState(float deltaTime, const glm::vec3& worldPos glm::vec3 forward = worldRotation * IDENTITY_FORWARD; glm::vec3 workingVelocity = worldVelocity; - + _flow.setTransform(sensorToWorldScale, worldPosition, worldRotation * Quaternions::Y_180); { glm::vec3 localVel = glm::inverse(worldRotation) * workingVelocity; @@ -1212,12 +1212,15 @@ void Rig::updateAnimations(float deltaTime, const glm::mat4& rootTransform, cons _networkVars = networkTriggersOut; _lastContext = context; } + applyOverridePoses(); buildAbsoluteRigPoses(_internalPoseSet._relativePoses, _internalPoseSet._absolutePoses); buildAbsoluteRigPoses(_networkPoseSet._relativePoses, _networkPoseSet._absolutePoses); // copy internal poses to external poses + _flow.update(); { QWriteLocker writeLock(&_externalPoseSetLock); + _externalPoseSet = _internalPoseSet; } } diff --git a/libraries/animation/src/Rig.h b/libraries/animation/src/Rig.h index 9bd2ed528a..50d13d348e 100644 --- a/libraries/animation/src/Rig.h +++ b/libraries/animation/src/Rig.h @@ -235,6 +235,7 @@ public: const AnimVariantMap& getAnimVars() const { return _lastAnimVars; } const AnimContext::DebugStateMachineMap& getStateMachineMap() const { return _lastContext.getStateMachineMap(); } void computeFlowSkeleton() { _flow.calculateConstraints(); } + const Flow& getFlow() const { return _flow; } signals: void onLoadComplete(); diff --git a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp index 07c1ca9a32..223813eecb 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp +++ b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp @@ -722,6 +722,24 @@ void Avatar::postUpdate(float deltaTime, const render::ScenePointer& scene) { DebugDraw::getInstance().drawRay(rightEyePosition, rightEyePosition + rightEyeRotation * Vectors::UNIT_Z * EYE_RAY_LENGTH, RED); } } + const bool DEBUG_FLOW = true; + if (_skeletonModel->isLoaded() && DEBUG_FLOW) { + auto flow = _skeletonModel->getRig().getFlow(); + auto joints = flow.getJoints(); + auto threads = flow.getThreads(); + for (auto &thread : threads) { + auto& jointIndexes = thread._joints; + for (size_t i = 1; i < jointIndexes.size(); i++) { + auto index1 = jointIndexes[i - 1]; + auto index2 = jointIndexes[i]; + // glm::vec3 pos1 = joint.second._node._currentPosition; + // glm::vec3 pos2 = joints.find(joint.second._parentIndex) != joints.end() ? joints[joint.second._parentIndex]._node._currentPosition : getJointPosition(joint.second._parentIndex); + // DebugDraw::getInstance().drawRay(pos1, pos2, glm::vec4(1.0f, 1.0f, 1.0f, 1.0f)); + DebugDraw::getInstance().drawRay(joints[index1]._node._currentPosition, joints[index2]._node._currentPosition, glm::vec4(1.0f, 1.0f, 1.0f, 1.0f)); + + } + } + } fixupModelsInScene(scene); updateFitBoundingBox(); From 9eceb1d0bd71759f51090ad70c52dc5a1e9add72 Mon Sep 17 00:00:00 2001 From: amantley Date: Thu, 7 Feb 2019 17:45:58 -0800 Subject: [PATCH 055/112] implemented the code for the heuristic elbows including code from the paper authors. to do: dampen the twist of the spine caused by the hand azimuth and put in the constraints for the wrists on the pole vector theta computation. --- .../src/AnimPoleVectorConstraint.cpp | 80 ++++++++++++++----- .../animation/src/AnimPoleVectorConstraint.h | 2 +- 2 files changed, 62 insertions(+), 20 deletions(-) diff --git a/libraries/animation/src/AnimPoleVectorConstraint.cpp b/libraries/animation/src/AnimPoleVectorConstraint.cpp index 55fbf20691..343d6338be 100644 --- a/libraries/animation/src/AnimPoleVectorConstraint.cpp +++ b/libraries/animation/src/AnimPoleVectorConstraint.cpp @@ -34,7 +34,31 @@ AnimPoleVectorConstraint::~AnimPoleVectorConstraint() { } -float AnimPoleVectorConstraint::findThetaNewWay(const glm::vec3& hand, const glm::vec3& shoulder) const { +static float correctElbowForHandRotation(const AnimPose& hand, const AnimPose& lowerArm) { + + // first calculate the ulnar/radial deviation + // use the lower arm x-axis and the hand x-axis + glm::vec3 xAxisLowerArm = lowerArm.rot() * glm::vec3(1.0f, 0.0f, 0.0f); + glm::vec3 yAxisLowerArm = lowerArm.rot() * glm::vec3(0.0f, 1.0f, 0.0f); + glm::vec3 zAxisLowerArm = lowerArm.rot() * glm::vec3(0.0f, 0.0f, 1.0f); + glm::vec3 xAxisHand = hand.rot() * glm::vec3(1.0f, 0.0f, 0.0f); + glm::vec3 yAxisHand = hand.rot() * glm::vec3(0.0f, 1.0f, 0.0f); + + float ulnarRadialDeviation = atan2(glm::dot(xAxisHand, xAxisLowerArm), glm::dot(xAxisHand, yAxisLowerArm)); + float flexionExtension = atan2(glm::dot(yAxisHand, zAxisLowerArm), glm::dot(yAxisHand, yAxisLowerArm)); + + qCDebug(animation) << "flexion angle " << flexionExtension; + + + float deltaInDegrees = (flexionExtension / PI) * 180.0f; + + qCDebug(animation) << "delta in degrees " << deltaInDegrees; + + float deltaFinal = glm::sign(deltaInDegrees) * powf(fabsf(deltaInDegrees/180.0f), 1.5f) * 180.0f * -0.3f; + return deltaFinal; +} + +float AnimPoleVectorConstraint::findThetaNewWay(const glm::vec3& hand, const glm::vec3& shoulder, bool left) const { // get the default poses for the upper and lower arm // then use this length to judge how far the arm is away from the shoulder. // then create weights that make the elbow angle less when the x value is large in either direction. @@ -45,27 +69,34 @@ float AnimPoleVectorConstraint::findThetaNewWay(const glm::vec3& hand, const glm AnimPose handPose = _skeleton->getAbsoluteDefaultPose(_skeleton->nameToJointIndex("RightHand")); // subtract 10 centimeters from the arm length for some reason actual arm position is clamped to length - 10cm. float defaultArmLength = glm::length( handPose.trans() - shoulderPose.trans() ) - 10.0f; - qCDebug(animation) << "default arm length " << defaultArmLength; + // qCDebug(animation) << "default arm length " << defaultArmLength; // phi_0 is the lowest angle we can have const float phi_0 = 15.0f; + const float zStart = 0.6f; + const float xStart = 0.1f; // biases - const glm::vec3 biases(30.0f, 120.0f, -30.0f); + //const glm::vec3 biases(30.0f, 120.0f, -30.0f); + const glm::vec3 biases(0.0f, 135.0f, 0.0f); // weights - const glm::vec3 weights(-30.0f, 30.0f, 210.0f); + const float zWeightBottom = -100.0f; + //const glm::vec3 weights(-30.0f, 30.0f, 210.0f); + const glm::vec3 weights(-50.0f, -60.0f, 260.0f); glm::vec3 armToHand = hand - shoulder; - qCDebug(animation) << "current arm length " << glm::length(armToHand); - float initial_valuesX = ((fabsf(armToHand[0]) / defaultArmLength) * weights[0]) + biases[0]; - float initial_valuesY = ((fabs(armToHand[1]) / defaultArmLength) * weights[1]) + biases[1]; - float initial_valuesZ = ((armToHand[2] / defaultArmLength) * weights[2]) + biases[2]; - if (initial_valuesX < 0.0f) { - initial_valuesX = 0.0f; + // qCDebug(animation) << "current arm length " << glm::length(armToHand); + float initial_valuesY = ((armToHand[1] / defaultArmLength) * weights[1]) + biases[1]; + float initial_valuesZ; + if (armToHand[1] > 0.0f) { + initial_valuesZ = weights[2] * glm::max(zStart - (armToHand[2] / defaultArmLength), 0.0f) * fabs(armToHand[1] / defaultArmLength); + } else { + initial_valuesZ = zWeightBottom * glm::max(zStart - (armToHand[2] / defaultArmLength), 0.0f) * fabs(armToHand[1] / defaultArmLength); } - if (initial_valuesY < 0.0f) { - initial_valuesY = 0.0f; - } - if (initial_valuesZ < 0.0f) { - initial_valuesZ = 0.0f; + + float initial_valuesX; + if (left) { + initial_valuesX = weights[0] * glm::max(-1.0f * (armToHand[0] / defaultArmLength) + xStart, 0.0f); + } else { + initial_valuesX = weights[0] * glm::max((armToHand[0] / defaultArmLength) + xStart, 0.0f); } float theta = initial_valuesX + initial_valuesY + initial_valuesZ; @@ -77,7 +108,7 @@ float AnimPoleVectorConstraint::findThetaNewWay(const glm::vec3& hand, const glm theta = 175.0f; } - qCDebug(animation) << "relative hand" << initial_valuesX << " " << initial_valuesY << " " << initial_valuesZ << "theta value for pole vector is " << theta; + // qCDebug(animation) << "relative hand" << initial_valuesX << " " << initial_valuesY << " " << initial_valuesZ << "theta value for pole vector is " << theta; return theta; } @@ -170,14 +201,25 @@ const AnimPoseVec& AnimPoleVectorConstraint::evaluate(const AnimVariantMap& anim float fred; if ((_skeleton->nameToJointIndex("RightHand") == _tipJointIndex) || (_skeleton->nameToJointIndex("LeftHand") == _tipJointIndex)) { - qCDebug(animation) << "theta from the old code " << theta; - fred = findThetaNewWay(tipPose.trans(), basePose.trans()); + //qCDebug(animation) << "theta from the old code " << theta; + bool isLeft = false; if (_skeleton->nameToJointIndex("LeftHand") == _tipJointIndex) { - fred = -1.0f * fred; + isLeft = true; + } + fred = findThetaNewWay(tipPose.trans(), basePose.trans(), isLeft); + if (isLeft){ + fred *= -1.0f; } theta = ((180.0f - fred) / 180.0f)*PI; + + // here is where we would do the wrist correction. + float deltaTheta = correctElbowForHandRotation(tipPose, midPose); + qCDebug(animation) << "the wrist correction theta is -----> " << deltaTheta; + } + + //glm::quat deltaRot = glm::angleAxis(theta, unitAxis); glm::quat deltaRot = glm::angleAxis(theta, unitAxis); diff --git a/libraries/animation/src/AnimPoleVectorConstraint.h b/libraries/animation/src/AnimPoleVectorConstraint.h index df8cddec7d..be3346974e 100644 --- a/libraries/animation/src/AnimPoleVectorConstraint.h +++ b/libraries/animation/src/AnimPoleVectorConstraint.h @@ -25,7 +25,7 @@ public: const QString& enabledVar, const QString& poleVectorVar); virtual ~AnimPoleVectorConstraint() override; - float findThetaNewWay(const glm::vec3& hand, const glm::vec3& shoulder) const; + float findThetaNewWay(const glm::vec3& hand, const glm::vec3& shoulder, bool left) const; virtual const AnimPoseVec& evaluate(const AnimVariantMap& animVars, const AnimContext& context, float dt, AnimVariantMap& triggersOut) override; From 822ec1c529fa6c5b82acba36e4bda7e491ad2b39 Mon Sep 17 00:00:00 2001 From: amantley Date: Fri, 8 Feb 2019 17:53:23 -0800 Subject: [PATCH 056/112] working on the wrist tweak, dampened the spine twist --- interface/src/avatar/MySkeletonModel.cpp | 1 + libraries/animation/src/AnimArmIK.cpp | 2 +- .../src/AnimPoleVectorConstraint.cpp | 77 +++++++++++++++---- 3 files changed, 65 insertions(+), 15 deletions(-) diff --git a/interface/src/avatar/MySkeletonModel.cpp b/interface/src/avatar/MySkeletonModel.cpp index 953b8a4c73..51a2c3767b 100755 --- a/interface/src/avatar/MySkeletonModel.cpp +++ b/interface/src/avatar/MySkeletonModel.cpp @@ -262,6 +262,7 @@ void MySkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) { if (spine2Exists && headExists && hipsExists) { AnimPose rigSpaceYaw(myAvatar->getSpine2RotationRigSpace()); + rigSpaceYaw.rot() = safeLerp(Quaternions::IDENTITY, rigSpaceYaw.rot(), 0.5f); glm::vec3 u, v, w; glm::vec3 fwd = rigSpaceYaw.rot() * glm::vec3(0.0f, 0.0f, 1.0f); glm::vec3 up = currentHeadPose.trans() - currentHipsPose.trans(); diff --git a/libraries/animation/src/AnimArmIK.cpp b/libraries/animation/src/AnimArmIK.cpp index ba720f1126..87606fe5d2 100644 --- a/libraries/animation/src/AnimArmIK.cpp +++ b/libraries/animation/src/AnimArmIK.cpp @@ -31,7 +31,7 @@ AnimArmIK::~AnimArmIK() { const AnimPoseVec& AnimArmIK::evaluate(const AnimVariantMap& animVars, const AnimContext& context, float dt, AnimVariantMap& triggersOut) { - qCDebug(animation) << "evaluating the arm IK"; + //qCDebug(animation) << "evaluating the arm IK"; _poses = AnimTwoBoneIK::evaluate(animVars, context, dt, triggersOut); //assert(_children.size() == 1); diff --git a/libraries/animation/src/AnimPoleVectorConstraint.cpp b/libraries/animation/src/AnimPoleVectorConstraint.cpp index 343d6338be..c3078dab02 100644 --- a/libraries/animation/src/AnimPoleVectorConstraint.cpp +++ b/libraries/animation/src/AnimPoleVectorConstraint.cpp @@ -34,7 +34,7 @@ AnimPoleVectorConstraint::~AnimPoleVectorConstraint() { } -static float correctElbowForHandRotation(const AnimPose& hand, const AnimPose& lowerArm) { +static float correctElbowForHandFlexionExtension(const AnimPose& hand, const AnimPose& lowerArm) { // first calculate the ulnar/radial deviation // use the lower arm x-axis and the hand x-axis @@ -44,18 +44,57 @@ static float correctElbowForHandRotation(const AnimPose& hand, const AnimPose& l glm::vec3 xAxisHand = hand.rot() * glm::vec3(1.0f, 0.0f, 0.0f); glm::vec3 yAxisHand = hand.rot() * glm::vec3(0.0f, 1.0f, 0.0f); - float ulnarRadialDeviation = atan2(glm::dot(xAxisHand, xAxisLowerArm), glm::dot(xAxisHand, yAxisLowerArm)); + //float ulnarRadialDeviation = atan2(glm::dot(xAxisHand, xAxisLowerArm), glm::dot(xAxisHand, yAxisLowerArm)); float flexionExtension = atan2(glm::dot(yAxisHand, zAxisLowerArm), glm::dot(yAxisHand, yAxisLowerArm)); - qCDebug(animation) << "flexion angle " << flexionExtension; + //qCDebug(animation) << "flexion angle " << flexionExtension; float deltaInDegrees = (flexionExtension / PI) * 180.0f; - qCDebug(animation) << "delta in degrees " << deltaInDegrees; + //qCDebug(animation) << "delta in degrees " << deltaInDegrees; float deltaFinal = glm::sign(deltaInDegrees) * powf(fabsf(deltaInDegrees/180.0f), 1.5f) * 180.0f * -0.3f; - return deltaFinal; + return deltaInDegrees;// deltaFinal; +} + +static float correctElbowForHandUlnarRadialDeviation(const AnimPose& hand, const AnimPose& lowerArm) { + + const float DEAD_ZONE = 0.3f; + const float FILTER_EXPONENT = 2.0f; + // first calculate the ulnar/radial deviation + // use the lower arm x-axis and the hand x-axis + glm::vec3 xAxisLowerArm = lowerArm.rot() * glm::vec3(1.0f, 0.0f, 0.0f); + glm::vec3 yAxisLowerArm = lowerArm.rot() * glm::vec3(0.0f, 1.0f, 0.0f); + glm::vec3 zAxisLowerArm = lowerArm.rot() * glm::vec3(0.0f, 0.0f, 1.0f); + glm::vec3 xAxisHand = hand.rot() * glm::vec3(1.0f, 0.0f, 0.0f); + glm::vec3 yAxisHand = hand.rot() * glm::vec3(0.0f, 1.0f, 0.0f); + + float ulnarRadialDeviation = atan2(glm::dot(xAxisHand, xAxisLowerArm), glm::dot(xAxisHand, yAxisLowerArm)); + //float flexionExtension = atan2(glm::dot(yAxisHand, zAxisLowerArm), glm::dot(yAxisHand, yAxisLowerArm)); + + + + float makeForwardZeroRadians = ulnarRadialDeviation - (PI / 2.0f); + + qCDebug(animation) << "calibrated ulnar " << makeForwardZeroRadians; + + float deltaFractionOfPi = (makeForwardZeroRadians / PI); + float deltaUlnarRadial; + if (fabsf(deltaFractionOfPi) < DEAD_ZONE) { + deltaUlnarRadial = 0.0f; + } else { + deltaUlnarRadial = (deltaFractionOfPi - glm::sign(deltaFractionOfPi) * DEAD_ZONE) / (1.0f - DEAD_ZONE); + } + + float deltaUlnarRadialDegrees = glm::sign(deltaUlnarRadial) * powf(fabsf(deltaUlnarRadial), FILTER_EXPONENT) * 180.0f; + + + + qCDebug(animation) << "ulnar delta in degrees " << deltaUlnarRadialDegrees; + + float deltaFinal = deltaUlnarRadialDegrees; + return deltaFractionOfPi * 180.0f; // deltaFinal; } float AnimPoleVectorConstraint::findThetaNewWay(const glm::vec3& hand, const glm::vec3& shoulder, bool left) const { @@ -81,10 +120,10 @@ float AnimPoleVectorConstraint::findThetaNewWay(const glm::vec3& hand, const glm // weights const float zWeightBottom = -100.0f; //const glm::vec3 weights(-30.0f, 30.0f, 210.0f); - const glm::vec3 weights(-50.0f, -60.0f, 260.0f); + const glm::vec3 weights(-50.0f, 60.0f, 260.0f); glm::vec3 armToHand = hand - shoulder; // qCDebug(animation) << "current arm length " << glm::length(armToHand); - float initial_valuesY = ((armToHand[1] / defaultArmLength) * weights[1]) + biases[1]; + float initial_valuesY = (fabsf(armToHand[1] / defaultArmLength) * weights[1]) + biases[1]; float initial_valuesZ; if (armToHand[1] > 0.0f) { initial_valuesZ = weights[2] * glm::max(zStart - (armToHand[2] / defaultArmLength), 0.0f) * fabs(armToHand[1] / defaultArmLength); @@ -96,7 +135,7 @@ float AnimPoleVectorConstraint::findThetaNewWay(const glm::vec3& hand, const glm if (left) { initial_valuesX = weights[0] * glm::max(-1.0f * (armToHand[0] / defaultArmLength) + xStart, 0.0f); } else { - initial_valuesX = weights[0] * glm::max((armToHand[0] / defaultArmLength) + xStart, 0.0f); + initial_valuesX = weights[0] * ((armToHand[0] / defaultArmLength) + xStart); } float theta = initial_valuesX + initial_valuesY + initial_valuesZ; @@ -108,7 +147,9 @@ float AnimPoleVectorConstraint::findThetaNewWay(const glm::vec3& hand, const glm theta = 175.0f; } - // qCDebug(animation) << "relative hand" << initial_valuesX << " " << initial_valuesY << " " << initial_valuesZ << "theta value for pole vector is " << theta; + if (!left) { + //qCDebug(animation) << "relative hand x " << initial_valuesX << " y " << initial_valuesY << " z " << initial_valuesZ << "theta value for pole vector is " << theta; + } return theta; } @@ -207,14 +248,22 @@ const AnimPoseVec& AnimPoleVectorConstraint::evaluate(const AnimVariantMap& anim isLeft = true; } fred = findThetaNewWay(tipPose.trans(), basePose.trans(), isLeft); - if (isLeft){ + + + // here is where we would do the wrist correction. + float deltaTheta = correctElbowForHandFlexionExtension(tipPose, midPose); + float deltaThetaUlnar; + if (!isLeft) { + deltaThetaUlnar = correctElbowForHandUlnarRadialDeviation(tipPose, midPose); + } + //fred -= deltaThetaUlnar; + fred -= deltaTheta; + + if (isLeft) { fred *= -1.0f; } theta = ((180.0f - fred) / 180.0f)*PI; - - // here is where we would do the wrist correction. - float deltaTheta = correctElbowForHandRotation(tipPose, midPose); - qCDebug(animation) << "the wrist correction theta is -----> " << deltaTheta; + //qCDebug(animation) << "the wrist correction theta is -----> " << isLeft << " theta: " << deltaTheta; } From f125e90449326c927aa861512ebb17cfbfe42150 Mon Sep 17 00:00:00 2001 From: Angus Antley Date: Mon, 11 Feb 2019 07:41:41 -0800 Subject: [PATCH 057/112] worked on the swing twist decomp to get the angles of the wrist for elbow adjustments --- .../src/AnimPoleVectorConstraint.cpp | 37 ++++++++++++++++--- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/libraries/animation/src/AnimPoleVectorConstraint.cpp b/libraries/animation/src/AnimPoleVectorConstraint.cpp index c3078dab02..09fadf2da5 100644 --- a/libraries/animation/src/AnimPoleVectorConstraint.cpp +++ b/libraries/animation/src/AnimPoleVectorConstraint.cpp @@ -77,7 +77,7 @@ static float correctElbowForHandUlnarRadialDeviation(const AnimPose& hand, const float makeForwardZeroRadians = ulnarRadialDeviation - (PI / 2.0f); - qCDebug(animation) << "calibrated ulnar " << makeForwardZeroRadians; + //qCDebug(animation) << "calibrated ulnar " << makeForwardZeroRadians; float deltaFractionOfPi = (makeForwardZeroRadians / PI); float deltaUlnarRadial; @@ -91,7 +91,7 @@ static float correctElbowForHandUlnarRadialDeviation(const AnimPose& hand, const - qCDebug(animation) << "ulnar delta in degrees " << deltaUlnarRadialDegrees; + //qCDebug(animation) << "ulnar delta in degrees " << deltaUlnarRadialDegrees; float deltaFinal = deltaUlnarRadialDegrees; return deltaFractionOfPi * 180.0f; // deltaFinal; @@ -99,7 +99,7 @@ static float correctElbowForHandUlnarRadialDeviation(const AnimPose& hand, const float AnimPoleVectorConstraint::findThetaNewWay(const glm::vec3& hand, const glm::vec3& shoulder, bool left) const { // get the default poses for the upper and lower arm - // then use this length to judge how far the arm is away from the shoulder. + // then use this length to judge how far the hand is away from the shoulder. // then create weights that make the elbow angle less when the x value is large in either direction. // make the angle less when z is small. // lower y with x center lower angle @@ -248,7 +248,34 @@ const AnimPoseVec& AnimPoleVectorConstraint::evaluate(const AnimVariantMap& anim isLeft = true; } fred = findThetaNewWay(tipPose.trans(), basePose.trans(), isLeft); - + + //get the swingTwist of the hand to lower arm + glm::quat yTwist; + glm::quat flexUlnarSwing; + glm::quat relativeHandRotation = (midPose.inverse() * tipPose).rot(); + swingTwistDecomposition(relativeHandRotation, Vectors::UNIT_X, flexUlnarSwing, yTwist); + glm::vec3 twistAxis = glm::axis(yTwist); + glm::vec3 flexUlnarAxis = glm::axis(flexUlnarSwing); + float swingTheta = glm::angle(flexUlnarSwing); + float twistTheta = glm::angle(yTwist); + glm::quat flex; + glm::quat ulnarDeviation; + swingTwistDecomposition(flexUlnarSwing, Vectors::UNIT_Z, flex, ulnarDeviation); + float flexTheta = glm::angle(flex); + glm::vec3 ulnarAxis = glm::axis(ulnarDeviation); + float ulnarDeviationTheta = glm::angle(ulnarDeviation); + + glm::vec3 eulerVersion = glm::eulerAngles(relativeHandRotation); + if (!isLeft) { + //qCDebug(animation) << "wrist thetas -----> X " << twistTheta << " twist: " << flexTheta << "ulnar deviation: " << ulnarDeviationTheta; + qCDebug(animation) << "0: " << eulerVersion[0] << " 1: " << eulerVersion[1] << " 2: " << eulerVersion[2]; + //qCDebug(animation) << "ulnarAxis " << flexUlnarAxis; + //qCDebug(animation) << "twistAxis " << twistAxis; + } + + //QString name = QString("wrist_target").arg(_id); + //glm::vec4 markerColor(1.0f, 1.0f, 0.0f, 0.0f); + //DebugDraw::getInstance().addMyAvatarMarker(name, midPose.rot(), midPose.trans(), markerColor); // here is where we would do the wrist correction. float deltaTheta = correctElbowForHandFlexionExtension(tipPose, midPose); @@ -262,7 +289,7 @@ const AnimPoseVec& AnimPoleVectorConstraint::evaluate(const AnimVariantMap& anim if (isLeft) { fred *= -1.0f; } - theta = ((180.0f - fred) / 180.0f)*PI; + // theta = ((180.0f - fred) / 180.0f)*PI; //qCDebug(animation) << "the wrist correction theta is -----> " << isLeft << " theta: " << deltaTheta; } From 942e9ccdfd4ddf7d920a07f1ce37f9a1ed6ed797 Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Mon, 11 Feb 2019 18:21:00 -0700 Subject: [PATCH 058/112] Hand collisions working --- interface/src/avatar/AvatarManager.cpp | 8 + interface/src/avatar/OtherAvatar.cpp | 1 - interface/src/avatar/OtherAvatar.h | 1 + libraries/animation/src/Flow.cpp | 245 ++++++++++++------------- libraries/animation/src/Flow.h | 69 ++++--- libraries/animation/src/Rig.h | 2 +- 6 files changed, 162 insertions(+), 164 deletions(-) diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index c9e099df21..50e8546979 100755 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -271,6 +271,14 @@ void AvatarManager::updateOtherAvatars(float deltaTime) { if (avatar->getSkeletonModel()->isLoaded()) { // remove the orb if it is there avatar->removeOrb(); + if (avatar->getWorkloadRegion() == workload::Region::R1) { + auto &flow = _myAvatar->getSkeletonModel()->getRig().getFlow(); + for (auto &handJointName : HAND_COLLISION_JOINTS) { + int jointIndex = avatar->getJointIndex(handJointName); + glm::vec3 position = avatar->getJointPosition(jointIndex); + flow.setOthersCollision(avatar->getID(), jointIndex, position); + } + } if (avatar->needsPhysicsUpdate()) { _avatarsToChangeInPhysics.insert(avatar); } diff --git a/interface/src/avatar/OtherAvatar.cpp b/interface/src/avatar/OtherAvatar.cpp index a3950c8e96..695481b709 100755 --- a/interface/src/avatar/OtherAvatar.cpp +++ b/interface/src/avatar/OtherAvatar.cpp @@ -365,7 +365,6 @@ void OtherAvatar::simulate(float deltaTime, bool inView) { PROFILE_RANGE(simulation, "grabs"); applyGrabChanges(); } - updateFadingStatus(); } diff --git a/interface/src/avatar/OtherAvatar.h b/interface/src/avatar/OtherAvatar.h index 3ecd35413f..6398be9313 100644 --- a/interface/src/avatar/OtherAvatar.h +++ b/interface/src/avatar/OtherAvatar.h @@ -50,6 +50,7 @@ public: void rebuildCollisionShape() override; void setWorkloadRegion(uint8_t region); + uint8_t getWorkloadRegion() { return _workloadRegion; } bool shouldBeInPhysicsSimulation() const; bool needsPhysicsUpdate() const; diff --git a/libraries/animation/src/Flow.cpp b/libraries/animation/src/Flow.cpp index a10d413d90..87d7155abd 100644 --- a/libraries/animation/src/Flow.cpp +++ b/libraries/animation/src/Flow.cpp @@ -12,11 +12,23 @@ #include "Rig.h" #include "AnimSkeleton.h" -FlowCollisionSphere::FlowCollisionSphere(const int& jointIndex, const FlowCollisionSettings& settings) { +const std::map PRESET_FLOW_DATA = { { "hair", FlowPhysicsSettings() }, +{ "skirt", FlowPhysicsSettings(true, 1.0f, DEFAULT_GRAVITY, 0.65f, 0.8f, 0.45f, 0.01f) }, +{ "breast", FlowPhysicsSettings(true, 1.0f, DEFAULT_GRAVITY, 0.65f, 0.8f, 0.45f, 0.01f) } }; + +const std::map PRESET_COLLISION_DATA = { + { "Spine2", FlowCollisionSettings(QUuid(), FlowCollisionType::CollisionSphere, glm::vec3(0.0f, 0.2f, 0.0f), 0.14f) }, + { "LeftArm", FlowCollisionSettings(QUuid(), FlowCollisionType::CollisionSphere, glm::vec3(0.0f, 0.02f, 0.0f), 0.05f) }, + { "RightArm", FlowCollisionSettings(QUuid(), FlowCollisionType::CollisionSphere, glm::vec3(0.0f, 0.02f, 0.0f), 0.05f) }, + { "HeadTop_End", FlowCollisionSettings(QUuid(), FlowCollisionType::CollisionSphere, glm::vec3(0.0f, -0.15f, 0.0f), 0.09f) } +}; + +FlowCollisionSphere::FlowCollisionSphere(const int& jointIndex, const FlowCollisionSettings& settings, bool isTouch) { _jointIndex = jointIndex; _radius = _initialRadius = settings._radius; _offset = _initialOffset = settings._offset; _entityID = settings._entityID; + _isTouch = isTouch; } FlowCollisionResult FlowCollisionSphere::computeSphereCollision(const glm::vec3& point, float radius) const { @@ -51,53 +63,21 @@ FlowCollisionResult FlowCollisionSphere::checkSegmentCollision(const glm::vec3& return result; } -void FlowCollisionSphere::update() { - // TODO - // Fill this +void FlowCollisionSystem::addCollisionSphere(int jointIndex, const FlowCollisionSettings& settings, const glm::vec3& position, bool isSelfCollision, bool isTouch) { + auto collision = FlowCollisionSphere(jointIndex, settings, isTouch); + collision.setPosition(position); + if (isSelfCollision) { + _selfCollisions.push_back(collision); + } else { + _othersCollisions.push_back(collision); + } + +}; +void FlowCollisionSystem::resetCollisions() { + _allCollisions.clear(); + _othersCollisions.clear(); + _selfCollisions.clear(); } - -void FlowCollisionSystem::addCollisionSphere(int jointIndex, const FlowCollisionSettings& settings) { - _collisionSpheres.push_back(FlowCollisionSphere(jointIndex, settings)); -}; - -void FlowCollisionSystem::addCollisionShape(int jointIndex, const FlowCollisionSettings& settings) { - auto name = JOINT_COLLISION_PREFIX + jointIndex; - switch (settings._type) { - case FlowCollisionType::CollisionSphere: - addCollisionSphere(jointIndex, settings); - break; - default: - break; - } -}; - -bool FlowCollisionSystem::addCollisionToJoint(int jointIndex) { - if (_collisionSpheres.size() >= COLLISION_SHAPES_LIMIT) { - return false; - } - int collisionIndex = findCollisionWithJoint(jointIndex); - if (collisionIndex == -1) { - addCollisionShape(jointIndex, FlowCollisionSettings()); - return true; - } - else { - return false; - } -}; - -void FlowCollisionSystem::removeCollisionFromJoint(int jointIndex) { - int collisionIndex = findCollisionWithJoint(jointIndex); - if (collisionIndex > -1) { - _collisionSpheres.erase(_collisionSpheres.begin() + collisionIndex); - } -}; - -void FlowCollisionSystem::update() { - for (size_t i = 0; i < _collisionSpheres.size(); i++) { - _collisionSpheres[i].update(); - } -}; - FlowCollisionResult FlowCollisionSystem::computeCollision(const std::vector collisions) { FlowCollisionResult result; if (collisions.size() > 1) { @@ -123,50 +103,51 @@ FlowCollisionResult FlowCollisionSystem::computeCollision(const std::vector FlowCollisionSystem::checkFlowThreadCollisions(FlowThread* flowThread, bool checkSegments) { +std::vector FlowCollisionSystem::checkFlowThreadCollisions(FlowThread* flowThread) { std::vector> FlowThreadResults; FlowThreadResults.resize(flowThread->_joints.size()); - for (size_t j = 0; j < _collisionSpheres.size(); j++) { - FlowCollisionSphere &sphere = _collisionSpheres[j]; + for (size_t j = 0; j < _allCollisions.size(); j++) { + FlowCollisionSphere &sphere = _allCollisions[j]; FlowCollisionResult rootCollision = sphere.computeSphereCollision(flowThread->_positions[0], flowThread->_radius); std::vector collisionData = { rootCollision }; bool tooFar = rootCollision._distance >(flowThread->_length + rootCollision._radius); FlowCollisionResult nextCollision; if (!tooFar) { - if (checkSegments) { + if (sphere._isTouch) { for (size_t i = 1; i < flowThread->_joints.size(); i++) { auto prevCollision = collisionData[i - 1]; - nextCollision = _collisionSpheres[j].computeSphereCollision(flowThread->_positions[i], flowThread->_radius); + nextCollision = _allCollisions[j].computeSphereCollision(flowThread->_positions[i], flowThread->_radius); collisionData.push_back(nextCollision); + bool isTouching = false; if (prevCollision._offset > 0.0f) { if (i == 1) { FlowThreadResults[i - 1].push_back(prevCollision); + isTouching = true; } - } - else if (nextCollision._offset > 0.0f) { + } else if (nextCollision._offset > 0.0f) { FlowThreadResults[i].push_back(nextCollision); - } - else { - FlowCollisionResult segmentCollision = _collisionSpheres[j].checkSegmentCollision(flowThread->_positions[i - 1], flowThread->_positions[i], prevCollision, nextCollision); + isTouching = true; + } else { + FlowCollisionResult segmentCollision = _allCollisions[j].checkSegmentCollision(flowThread->_positions[i - 1], flowThread->_positions[i], prevCollision, nextCollision); if (segmentCollision._offset > 0) { FlowThreadResults[i - 1].push_back(segmentCollision); FlowThreadResults[i].push_back(segmentCollision); + isTouching = true; } } } - } - else { + } else { if (rootCollision._offset > 0.0f) { FlowThreadResults[0].push_back(rootCollision); } for (size_t i = 1; i < flowThread->_joints.size(); i++) { - nextCollision = _collisionSpheres[j].computeSphereCollision(flowThread->_positions[i], flowThread->_radius); + nextCollision = _allCollisions[j].computeSphereCollision(flowThread->_positions[i], flowThread->_radius); if (nextCollision._offset > 0.0f) { FlowThreadResults[i].push_back(nextCollision); } @@ -182,40 +163,49 @@ std::vector FlowCollisionSystem::checkFlowThreadCollisions( return results; }; -int FlowCollisionSystem::findCollisionWithJoint(int jointIndex) { - for (size_t i = 0; i < _collisionSpheres.size(); i++) { - if (_collisionSpheres[i]._jointIndex == jointIndex) { +int FlowCollisionSystem::findSelfCollisionWithJoint(int jointIndex) { + for (size_t i = 0; i < _selfCollisions.size(); i++) { + if (_selfCollisions[i]._jointIndex == jointIndex) { return (int)i; } } return -1; }; -void FlowCollisionSystem::modifyCollisionRadius(int jointIndex, float radius) { - int collisionIndex = findCollisionWithJoint(jointIndex); +void FlowCollisionSystem::modifySelfCollisionRadius(int jointIndex, float radius) { + int collisionIndex = findSelfCollisionWithJoint(jointIndex); if (collisionIndex > -1) { - _collisionSpheres[collisionIndex]._initialRadius = radius; - _collisionSpheres[collisionIndex]._radius = _scale * radius; + _selfCollisions[collisionIndex]._initialRadius = radius; + _selfCollisions[collisionIndex]._radius = _scale * radius; } }; -void FlowCollisionSystem::modifyCollisionYOffset(int jointIndex, float offset) { - int collisionIndex = findCollisionWithJoint(jointIndex); +void FlowCollisionSystem::modifySelfCollisionYOffset(int jointIndex, float offset) { + int collisionIndex = findSelfCollisionWithJoint(jointIndex); if (collisionIndex > -1) { - auto currentOffset = _collisionSpheres[collisionIndex]._offset; - _collisionSpheres[collisionIndex]._initialOffset = glm::vec3(currentOffset.x, offset, currentOffset.z); - _collisionSpheres[collisionIndex]._offset = _collisionSpheres[collisionIndex]._initialOffset * _scale; + auto currentOffset = _selfCollisions[collisionIndex]._offset; + _selfCollisions[collisionIndex]._initialOffset = glm::vec3(currentOffset.x, offset, currentOffset.z); + _selfCollisions[collisionIndex]._offset = _selfCollisions[collisionIndex]._initialOffset * _scale; } }; -void FlowCollisionSystem::modifyCollisionOffset(int jointIndex, const glm::vec3& offset) { - int collisionIndex = findCollisionWithJoint(jointIndex); +void FlowCollisionSystem::modifySelfCollisionOffset(int jointIndex, const glm::vec3& offset) { + int collisionIndex = findSelfCollisionWithJoint(jointIndex); if (collisionIndex > -1) { - _collisionSpheres[collisionIndex]._initialOffset = offset; - _collisionSpheres[collisionIndex]._offset = _collisionSpheres[collisionIndex]._initialOffset * _scale; + _selfCollisions[collisionIndex]._initialOffset = offset; + _selfCollisions[collisionIndex]._offset = _selfCollisions[collisionIndex]._initialOffset * _scale; } }; + +void FlowCollisionSystem::prepareCollisions() { + _allCollisions.clear(); + _allCollisions.resize(_selfCollisions.size() + _othersCollisions.size()); + std::copy(_selfCollisions.begin(), _selfCollisions.begin() + _selfCollisions.size(), _allCollisions.begin()); + std::copy(_othersCollisions.begin(), _othersCollisions.begin() + _othersCollisions.size(), _allCollisions.begin() + _selfCollisions.size()); + _othersCollisions.clear(); +} + void FlowNode::update(const glm::vec3& accelerationOffset) { _acceleration = glm::vec3(0.0f, _settings._gravity, 0.0f); _previousVelocity = _currentVelocity; @@ -263,16 +253,6 @@ void FlowNode::solveCollisions(const FlowCollisionResult& collision) { } }; -void FlowNode::apply(const QString& name, bool forceRendering) { - // TODO - // Render here ?? - /* - jointDebug.setDebugSphere(name, self.currentPosition, 2 * self.radius, { red: self.collision && self.collision.collisionCount > 1 ? 0 : 255, - green : self.colliding ? 0 : 255, - blue : 0 }, forceRendering); - */ -}; - FlowJoint::FlowJoint(int jointIndex, int parentIndex, int childIndex, const QString& name, const QString& group, float scale, const FlowPhysicsSettings& settings) { _index = jointIndex; _name = name; @@ -347,7 +327,7 @@ void FlowThread::resetLength() { _length = 0.0f; for (size_t i = 1; i < _joints.size(); i++) { int index = _joints[i]; - _length += (*_jointsPointer)[index]._length; + _length += _jointsPointer->at(index)._length; } } @@ -356,12 +336,12 @@ void FlowThread::computeFlowThread(int rootIndex) { if (_jointsPointer->size() == 0) { return; } - int childIndex = (*_jointsPointer)[parentIndex]._childIndex; + int childIndex = _jointsPointer->at(parentIndex)._childIndex; std::vector indexes = { parentIndex }; for (size_t i = 0; i < _jointsPointer->size(); i++) { if (childIndex > -1) { indexes.push_back(childIndex); - childIndex = (*_jointsPointer)[childIndex]._childIndex; + childIndex = _jointsPointer->at(childIndex)._childIndex; } else { break; } @@ -370,20 +350,20 @@ void FlowThread::computeFlowThread(int rootIndex) { int index = indexes[i]; _joints.push_back(index); if (i > 0) { - _length += (*_jointsPointer)[index]._length; + _length += _jointsPointer->at(index)._length; } } }; void FlowThread::computeRecovery() { int parentIndex = _joints[0]; - auto parentJoint = (*_jointsPointer)[parentIndex]; - (*_jointsPointer)[parentIndex]._recoveryPosition = parentJoint._recoveryPosition = parentJoint._node._currentPosition; + auto parentJoint = _jointsPointer->at(parentIndex); + _jointsPointer->at(parentIndex)._recoveryPosition = parentJoint._recoveryPosition = parentJoint._node._currentPosition; glm::quat parentRotation = parentJoint._parentWorldRotation * parentJoint._initialRotation; for (size_t i = 1; i < _joints.size(); i++) { - auto joint = (*_jointsPointer)[_joints[i]]; + auto joint = _jointsPointer->at(_joints[i]); glm::quat rotation = i == 1 ? parentRotation : rotation * parentJoint._initialRotation; - (*_jointsPointer)[_joints[i]]._recoveryPosition = joint._recoveryPosition = parentJoint._recoveryPosition + (rotation * (joint._initialTranslation * 0.01f)); + _jointsPointer->at(_joints[i])._recoveryPosition = joint._recoveryPosition = parentJoint._recoveryPosition + (rotation * (joint._initialTranslation * 0.01f)); parentJoint = joint; } }; @@ -391,10 +371,10 @@ void FlowThread::computeRecovery() { void FlowThread::update() { if (getActive()) { _positions.clear(); - _radius = (*_jointsPointer)[_joints[0]]._node._settings._radius; + _radius = _jointsPointer->at(_joints[0])._node._settings._radius; computeRecovery(); for (size_t i = 0; i < _joints.size(); i++) { - auto &joint = (*_jointsPointer)[_joints[i]]; + auto &joint = _jointsPointer->at(_joints[i]); joint.update(); _positions.push_back(joint._node._currentPosition); } @@ -404,20 +384,16 @@ void FlowThread::update() { void FlowThread::solve(bool useCollisions, FlowCollisionSystem& collisionSystem) { if (getActive()) { if (useCollisions) { - auto bodyCollisions = collisionSystem.checkFlowThreadCollisions(this, false); + auto bodyCollisions = collisionSystem.checkFlowThreadCollisions(this); int handTouchedJoint = -1; for (size_t i = 0; i < _joints.size(); i++) { int index = _joints[i]; - if (bodyCollisions[i]._offset > 0.0f) { - (*_jointsPointer)[index].solve(bodyCollisions[i]); - } else { - (*_jointsPointer)[index].solve(FlowCollisionResult()); - } + _jointsPointer->at(index).solve(bodyCollisions[i]); } } else { for (size_t i = 0; i < _joints.size(); i++) { int index = _joints[i]; - (*_jointsPointer)[index].solve(FlowCollisionResult()); + _jointsPointer->at(index).solve(FlowCollisionResult()); } } } @@ -428,8 +404,8 @@ void FlowThread::computeJointRotations() { auto pos0 = _rootFramePositions[0]; auto pos1 = _rootFramePositions[1]; - auto joint0 = (*_jointsPointer)[_joints[0]]; - auto joint1 = (*_jointsPointer)[_joints[1]]; + auto joint0 = _jointsPointer->at(_joints[0]); + auto joint1 = _jointsPointer->at(_joints[1]); auto initial_pos1 = pos0 + (joint0._initialRotation * (joint1._initialTranslation * 0.01f)); @@ -438,10 +414,10 @@ void FlowThread::computeJointRotations() { auto delta = rotationBetween(vec0, vec1); - joint0._currentRotation = (*_jointsPointer)[_joints[0]]._currentRotation = delta * joint0._initialRotation; + joint0._currentRotation = _jointsPointer->at(_joints[0])._currentRotation = delta * joint0._initialRotation; for (size_t i = 1; i < _joints.size() - 1; i++) { - auto nextJoint = (*_jointsPointer)[_joints[i + 1]]; + auto nextJoint = _jointsPointer->at(_joints[i + 1]); for (size_t j = i; j < _joints.size(); j++) { _rootFramePositions[j] = glm::inverse(joint0._currentRotation) * _rootFramePositions[j] - (joint0._initialTranslation * 0.01f); } @@ -454,7 +430,7 @@ void FlowThread::computeJointRotations() { delta = rotationBetween(vec0, vec1); - joint1._currentRotation = (*_jointsPointer)[joint1._index]._currentRotation = delta * joint1._initialRotation; + joint1._currentRotation = _jointsPointer->at(joint1._index)._currentRotation = delta * joint1._initialRotation; joint0 = joint1; joint1 = nextJoint; } @@ -468,7 +444,7 @@ void FlowThread::apply() { }; bool FlowThread::getActive() { - return (*_jointsPointer)[_joints[0]]._node._active; + return _jointsPointer->at(_joints[0])._node._active; }; void Flow::setRig(Rig* rig) { @@ -484,12 +460,17 @@ void Flow::calculateConstraints() { auto flowPrefix = FLOW_JOINT_PREFIX.toUpper(); auto simPrefix = SIM_JOINT_PREFIX.toUpper(); auto skeleton = _rig->getAnimSkeleton(); + std::vector handsIndices; + _collisionSystem.resetCollisions(); if (skeleton) { for (int i = 0; i < skeleton->getNumJoints(); i++) { auto name = skeleton->getJointName(i); if (name == "RightHand") { rightHandIndex = i; } + if (std::find(HAND_COLLISION_JOINTS.begin(), HAND_COLLISION_JOINTS.end(), name) != HAND_COLLISION_JOINTS.end()) { + handsIndices.push_back(i); + } auto parentIndex = skeleton->getParentIndex(i); if (parentIndex == -1) { continue; @@ -533,7 +514,7 @@ void Flow::calculateConstraints() { } } else { if (PRESET_COLLISION_DATA.find(name) != PRESET_COLLISION_DATA.end()) { - _collisionSystem.addCollisionShape(i, PRESET_COLLISION_DATA.at(name)); + _collisionSystem.addCollisionSphere(i, PRESET_COLLISION_DATA.at(name)); } } if (isFlowJoint || isSimJoint) { @@ -591,8 +572,6 @@ void Flow::calculateConstraints() { if (_jointThreads.size() == 0) { _rig->clearJointStates(); } - - if (SHOW_DUMMY_JOINTS && rightHandIndex > -1) { int jointCount = (int)_flowJointData.size(); int extraIndex = (int)_flowJointData.size(); @@ -611,6 +590,13 @@ void Flow::calculateConstraints() { auto extraThread = FlowThread(jointCount, &_flowJointData); _jointThreads.push_back(extraThread); } + if (handsIndices.size() > 0) { + FlowCollisionSettings handSettings; + handSettings._radius = HAND_COLLISION_RADIUS; + for (size_t i = 0; i < handsIndices.size(); i++) { + _collisionSystem.addCollisionSphere(handsIndices[i], handSettings, glm::vec3(), true, true); + } + } _initialized = _jointThreads.size() > 0; } @@ -633,12 +619,10 @@ void Flow::setTransform(float scale, const glm::vec3& position, const glm::quat& } void Flow::update() { + QElapsedTimer _timer; _timer.start(); if (_initialized && _active) { updateJoints(); - if (USE_COLLISIONS) { - _collisionSystem.update(); - } int count = 0; for (auto &thread : _jointThreads) { thread.update(); @@ -650,11 +634,12 @@ void Flow::update() { } setJoints(); } - _elapsedTime = ((1.0 - _tau) * _elapsedTime + _tau * _timer.nsecsElapsed()); - _deltaTime += _elapsedTime; + _deltaTime += _timer.nsecsElapsed(); + _updates++; if (_deltaTime > _deltaTimeLimit) { - qDebug() << "Flow C++ update" << _elapsedTime; - _deltaTime = 0.0; + qDebug() << "Flow C++ update " << _deltaTime / _updates << " nanoSeconds"; + _deltaTime = 0; + _updates = 0; } } @@ -697,10 +682,15 @@ void Flow::updateJoints() { _rig->getJointRotationInWorldFrame(jointData.second._parentIndex, parentWorldRotation, _entityRotation); jointData.second.setUpdatedData(jointPosition, jointTranslation, jointRotation, parentPosition, parentWorldRotation); } - auto &collisions = _collisionSystem.getCollisions(); - for (auto &collision : collisions) { + auto &selfCollisions = _collisionSystem.getSelfCollisions(); + for (auto &collision : selfCollisions) { + glm::quat jointRotation; _rig->getJointPositionInWorldFrame(collision._jointIndex, collision._position, _entityPosition, _entityRotation); + _rig->getJointRotationInWorldFrame(collision._jointIndex, jointRotation, _entityRotation); + glm::vec3 worldOffset = jointRotation * collision._offset; + collision._position = collision._position + worldOffset; } + _collisionSystem.prepareCollisions(); } void Flow::setJoints() { @@ -712,3 +702,10 @@ void Flow::setJoints() { } } } + +void Flow::setOthersCollision(const QUuid& otherId, int jointIndex, const glm::vec3& position) { + FlowCollisionSettings settings; + settings._entityID = otherId; + settings._radius = HAND_COLLISION_RADIUS; + _collisionSystem.addCollisionSphere(jointIndex, settings, position, false, true); +} \ No newline at end of file diff --git a/libraries/animation/src/Flow.h b/libraries/animation/src/Flow.h index c93cf91673..ec98b32265 100644 --- a/libraries/animation/src/Flow.h +++ b/libraries/animation/src/Flow.h @@ -39,6 +39,8 @@ const float HAPTIC_THRESHOLD = 40.0f; const QString FLOW_JOINT_PREFIX = "flow"; const QString SIM_JOINT_PREFIX = "sim"; +const std::vector HAND_COLLISION_JOINTS = { "RightHandMiddle1", "RightHandThumb3", "LeftHandMiddle1", "LeftHandThumb3", "RightHandMiddle3", "LeftHandMiddle3" }; + const QString JOINT_COLLISION_PREFIX = "joint_"; const QString HAND_COLLISION_PREFIX = "hand_"; const float HAND_COLLISION_RADIUS = 0.03f; @@ -100,18 +102,6 @@ struct FlowCollisionSettings { const FlowPhysicsSettings DEFAULT_JOINT_SETTINGS; -const std::map PRESET_FLOW_DATA = { {"hair", FlowPhysicsSettings()}, - {"skirt", FlowPhysicsSettings(true, 1.0f, DEFAULT_GRAVITY, 0.65f, 0.8f, 0.45f, 0.01f)}, - {"breast", FlowPhysicsSettings(true, 1.0f, DEFAULT_GRAVITY, 0.65f, 0.8f, 0.45f, 0.01f)} }; - -const std::map PRESET_COLLISION_DATA = { - { "Head", FlowCollisionSettings(QUuid(), FlowCollisionType::CollisionSphere, glm::vec3(0.0f, 0.06f, 0.0f), 0.08f)}, - { "LeftArm", FlowCollisionSettings(QUuid(), FlowCollisionType::CollisionSphere, glm::vec3(0.0f, 0.02f, 0.0f), 0.05f) }, - { "Head", FlowCollisionSettings(QUuid(), FlowCollisionType::CollisionSphere, glm::vec3(0.0f, 0.04f, 0.0f), 0.0f) } -}; - -const std::vector HAND_COLLISION_JOINTS = { "RightHandMiddle1", "RightHandThumb3", "LeftHandMiddle1", "LeftHandThumb3", "RightHandMiddle3", "LeftHandMiddle3" }; - struct FlowJointInfo { FlowJointInfo() {}; FlowJointInfo(int index, int parentIndex, int childIndex, const QString& name) { @@ -138,19 +128,22 @@ struct FlowCollisionResult { class FlowCollisionSphere { public: FlowCollisionSphere() {}; - FlowCollisionSphere(const int& jointIndex, const FlowCollisionSettings& settings); + FlowCollisionSphere(const int& jointIndex, const FlowCollisionSettings& settings, bool isTouch = false); void setPosition(const glm::vec3& position) { _position = position; } FlowCollisionResult computeSphereCollision(const glm::vec3& point, float radius) const; FlowCollisionResult checkSegmentCollision(const glm::vec3& point1, const glm::vec3& point2, const FlowCollisionResult& collisionResult1, const FlowCollisionResult& collisionResult2); - void update(); QUuid _entityID; - int _jointIndex { -1 }; - float _radius { 0.0f }; - float _initialRadius{ 0.0f }; + glm::vec3 _offset; glm::vec3 _initialOffset; glm::vec3 _position; + + bool _isTouch { false }; + int _jointIndex { -1 }; + int collisionIndex { -1 }; + float _radius { 0.0f }; + float _initialRadius{ 0.0f }; }; class FlowThread; @@ -158,24 +151,26 @@ class FlowThread; class FlowCollisionSystem { public: FlowCollisionSystem() {}; - void addCollisionSphere(int jointIndex, const FlowCollisionSettings& settings); - void addCollisionShape(int jointIndex, const FlowCollisionSettings& settings); - bool addCollisionToJoint(int jointIndex); - void removeCollisionFromJoint(int jointIndex); - void update(); + void addCollisionSphere(int jointIndex, const FlowCollisionSettings& settings, const glm::vec3& position = { 0.0f, 0.0f, 0.0f }, bool isSelfCollision = true, bool isTouch = false); FlowCollisionResult computeCollision(const std::vector collisions); void setScale(float scale); - std::vector checkFlowThreadCollisions(FlowThread* flowThread, bool checkSegments); + std::vector checkFlowThreadCollisions(FlowThread* flowThread); - int findCollisionWithJoint(int jointIndex); - void modifyCollisionRadius(int jointIndex, float radius); - void modifyCollisionYOffset(int jointIndex, float offset); - void modifyCollisionOffset(int jointIndex, const glm::vec3& offset); + int findSelfCollisionWithJoint(int jointIndex); + void modifySelfCollisionRadius(int jointIndex, float radius); + void modifySelfCollisionYOffset(int jointIndex, float offset); + void modifySelfCollisionOffset(int jointIndex, const glm::vec3& offset); - std::vector& getCollisions() { return _collisionSpheres; }; -private: - std::vector _collisionSpheres; + std::vector& getSelfCollisions() { return _selfCollisions; }; + void setOthersCollisions(const std::vector& othersCollisions) { _othersCollisions = othersCollisions; } + void prepareCollisions(); + void resetCollisions(); + void resetOthersCollisions() { _othersCollisions.clear(); } +protected: + std::vector _selfCollisions; + std::vector _othersCollisions; + std::vector _allCollisions; float _scale{ 1.0f }; }; @@ -208,7 +203,6 @@ public: void solve(const glm::vec3& constrainPoint, float maxDistance, const FlowCollisionResult& collision); void solveConstraints(const glm::vec3& constrainPoint, float maxDistance); void solveCollisions(const FlowCollisionResult& collision); - void apply(const QString& name, bool forceRendering); }; class FlowJoint { @@ -268,7 +262,7 @@ public: void computeJointRotations(); void apply(); bool getActive(); - void setRootFramePositions(const std::vector& rootFramePositions) { _rootFramePositions = rootFramePositions; }; + void setRootFramePositions(const std::vector& rootFramePositions) { _rootFramePositions = rootFramePositions; } std::vector _joints; std::vector _positions; @@ -276,7 +270,6 @@ public: float _length{ 0.0f }; std::map* _jointsPointer; std::vector _rootFramePositions; - }; class Flow { @@ -288,6 +281,8 @@ public: void setTransform(float scale, const glm::vec3& position, const glm::quat& rotation); const std::map& getJoints() const { return _flowJointData; } const std::vector& getThreads() const { return _jointThreads; } + void setOthersCollision(const QUuid& otherId, int jointIndex, const glm::vec3& position); + FlowCollisionSystem& getCollisionSystem() { return _collisionSystem; } private: void setJoints(); void cleanUp(); @@ -305,11 +300,9 @@ private: FlowCollisionSystem _collisionSystem; bool _initialized { false }; bool _active { false }; - int _deltaTime{ 0 }; - int _deltaTimeLimit{ 4000 }; - int _elapsedTime{ 0 }; - float _tau = 0.1f; - QElapsedTimer _timer; + int _deltaTime { 0 }; + int _deltaTimeLimit { 4000000 }; + int _updates { 0 }; }; #endif // hifi_Flow_h diff --git a/libraries/animation/src/Rig.h b/libraries/animation/src/Rig.h index 50d13d348e..47c9697dac 100644 --- a/libraries/animation/src/Rig.h +++ b/libraries/animation/src/Rig.h @@ -235,7 +235,7 @@ public: const AnimVariantMap& getAnimVars() const { return _lastAnimVars; } const AnimContext::DebugStateMachineMap& getStateMachineMap() const { return _lastContext.getStateMachineMap(); } void computeFlowSkeleton() { _flow.calculateConstraints(); } - const Flow& getFlow() const { return _flow; } + Flow& getFlow() { return _flow; } signals: void onLoadComplete(); From bb29e382f0bf40f96ff1418d1f0637f62cceadb7 Mon Sep 17 00:00:00 2001 From: amantley Date: Mon, 11 Feb 2019 18:05:29 -0800 Subject: [PATCH 059/112] tweaking the hand pose correction on the pole vector --- .../src/AnimPoleVectorConstraint.cpp | 84 +++++++++++++++---- 1 file changed, 66 insertions(+), 18 deletions(-) diff --git a/libraries/animation/src/AnimPoleVectorConstraint.cpp b/libraries/animation/src/AnimPoleVectorConstraint.cpp index 09fadf2da5..0fa2ce0ee0 100644 --- a/libraries/animation/src/AnimPoleVectorConstraint.cpp +++ b/libraries/animation/src/AnimPoleVectorConstraint.cpp @@ -250,27 +250,51 @@ const AnimPoseVec& AnimPoleVectorConstraint::evaluate(const AnimVariantMap& anim fred = findThetaNewWay(tipPose.trans(), basePose.trans(), isLeft); //get the swingTwist of the hand to lower arm - glm::quat yTwist; - glm::quat flexUlnarSwing; - glm::quat relativeHandRotation = (midPose.inverse() * tipPose).rot(); - swingTwistDecomposition(relativeHandRotation, Vectors::UNIT_X, flexUlnarSwing, yTwist); - glm::vec3 twistAxis = glm::axis(yTwist); - glm::vec3 flexUlnarAxis = glm::axis(flexUlnarSwing); - float swingTheta = glm::angle(flexUlnarSwing); - float twistTheta = glm::angle(yTwist); glm::quat flex; + glm::quat twistUlnarSwing; + glm::quat relativeHandRotation = (midPose.inverse() * tipPose).rot(); + swingTwistDecomposition(relativeHandRotation, Vectors::UNIT_X, twistUlnarSwing, flex); + glm::vec3 flexAxis = glm::axis(flex); + + //float swingTheta = glm::angle(twistUlnarSwing); + float flexTheta = glm::sign(flexAxis[0]) * glm::angle(flex); + glm::quat twist; glm::quat ulnarDeviation; - swingTwistDecomposition(flexUlnarSwing, Vectors::UNIT_Z, flex, ulnarDeviation); - float flexTheta = glm::angle(flex); + swingTwistDecomposition(twistUlnarSwing, Vectors::UNIT_Z, twist, ulnarDeviation); + + glm::vec3 twistAxis = glm::axis(twist); glm::vec3 ulnarAxis = glm::axis(ulnarDeviation); - float ulnarDeviationTheta = glm::angle(ulnarDeviation); + float twistTheta = glm::sign(twistAxis[1]) * glm::angle(twist); + float ulnarDeviationTheta = glm::sign(ulnarAxis[2]) * glm::angle(ulnarDeviation); - glm::vec3 eulerVersion = glm::eulerAngles(relativeHandRotation); + glm::quat trueTwist; + glm::quat nonTwist; + swingTwistDecomposition(relativeHandRotation, Vectors::UNIT_Y, nonTwist, trueTwist); + if (trueTwist.w < 0.0f) { + trueTwist.x *= -1.0f; + trueTwist.y *= -1.0f; + trueTwist.z *= -1.0f; + trueTwist.w *= -1.0f; + } + glm::vec3 trueTwistAxis = glm::axis(trueTwist); + float trueTwistTheta = glm::angle(trueTwist); + trueTwistTheta *= glm::sign(trueTwistAxis[1]) * glm::angle(trueTwist); + //while (trueTwistTheta > PI) { + // trueTwistTheta -= 2.0f * PI; + //} + + + // glm::vec3 eulerVersion = glm::eulerAngles(relativeHandRotation); if (!isLeft) { - //qCDebug(animation) << "wrist thetas -----> X " << twistTheta << " twist: " << flexTheta << "ulnar deviation: " << ulnarDeviationTheta; - qCDebug(animation) << "0: " << eulerVersion[0] << " 1: " << eulerVersion[1] << " 2: " << eulerVersion[2]; + //qCDebug(animation) << "flex: " << (flexTheta / PI) * 180.0f << " twist: " << (twistTheta / PI) * 180.0f << " ulnar deviation: " << (ulnarDeviationTheta / PI) * 180.0f; + qCDebug(animation) << "trueTwist: " << (trueTwistTheta / PI) * 180.0f;// << " old twist: " << (twistTheta / PI) * 180.0f; //qCDebug(animation) << "ulnarAxis " << flexUlnarAxis; - //qCDebug(animation) << "twistAxis " << twistAxis; + qCDebug(animation) << "relative hand rotation " << relativeHandRotation; + qCDebug(animation) << "twist rotation " << trueTwist; + + //QString name = QString("handMarker3"); + //const vec4 WHITE(1.0f); + //DebugDraw::getInstance().addMyAvatarMarker(name, relativeHandRotation, midPose.trans(), WHITE); } //QString name = QString("wrist_target").arg(_id); @@ -283,13 +307,37 @@ const AnimPoseVec& AnimPoleVectorConstraint::evaluate(const AnimVariantMap& anim if (!isLeft) { deltaThetaUlnar = correctElbowForHandUlnarRadialDeviation(tipPose, midPose); } - //fred -= deltaThetaUlnar; - fred -= deltaTheta; + // make the dead zone PI/6.0 + + const float POWER = 4.0f; + /* + if (fabsf(flexTheta) > (PI / 6.0f)) { + fred -= glm::sign(flexTheta) * pow(flexTheta / PI, POWER) * 180.0f; + } + if (fabsf(ulnarDeviationTheta) > (PI / 6.0f)) { + if (trueTwistTheta > 0.0f) { + fred -= glm::sign(ulnarDeviationTheta) * pow(ulnarDeviationTheta / PI, POWER) * 180.0f; + } else { + fred += glm::sign(ulnarDeviationTheta) * pow(ulnarDeviationTheta / PI, POWER) * 180.0f; + } + } + */ + // remember direction of travel. + const float TWIST_DEADZONE = PI / 2.0f; + if (trueTwistTheta < -TWIST_DEADZONE) { + fred += glm::sign(trueTwistTheta) * pow((trueTwistTheta / PI), POWER) * 180.0f + pow(TWIST_DEADZONE / PI, POWER) * 180.0f; + } else { + if (trueTwistTheta > (PI / 2.0f)) { + fred += glm::sign(trueTwistTheta) * pow((trueTwistTheta / PI), POWER) * 180.0f - pow(TWIST_DEADZONE / PI, POWER) * 180.0f; + } + } + if (isLeft) { fred *= -1.0f; } - // theta = ((180.0f - fred) / 180.0f)*PI; + theta = ((180.0f - fred) / 180.0f)*PI; + //qCDebug(animation) << "the wrist correction theta is -----> " << isLeft << " theta: " << deltaTheta; } From 7bb353742aae95fe34c8415c03c760fca4e4e43c Mon Sep 17 00:00:00 2001 From: Angus Antley Date: Tue, 12 Feb 2019 07:40:18 -0800 Subject: [PATCH 060/112] more tweaks to get the wrist action right --- .../src/AnimPoleVectorConstraint.cpp | 49 ++++++++++++++----- 1 file changed, 37 insertions(+), 12 deletions(-) diff --git a/libraries/animation/src/AnimPoleVectorConstraint.cpp b/libraries/animation/src/AnimPoleVectorConstraint.cpp index 0fa2ce0ee0..b50f6dc280 100644 --- a/libraries/animation/src/AnimPoleVectorConstraint.cpp +++ b/libraries/animation/src/AnimPoleVectorConstraint.cpp @@ -310,29 +310,54 @@ const AnimPoseVec& AnimPoleVectorConstraint::evaluate(const AnimVariantMap& anim // make the dead zone PI/6.0 - const float POWER = 4.0f; + const float POWER = 2.0f; + const float FLEX_BOUNDARY = PI / 2.0f; + const float EXTEND_BOUNDARY = -PI / 4.0f; /* - if (fabsf(flexTheta) > (PI / 6.0f)) { - fred -= glm::sign(flexTheta) * pow(flexTheta / PI, POWER) * 180.0f; + if (flexTheta > FLEX_BOUNDARY) { + fred -= glm::sign(flexTheta) * pow((flexTheta - FLEX_BOUNDARY) / PI, POWER) * 180.0f; + } else if (flexTheta < EXTEND_BOUNDARY) { + fred -= glm::sign(flexTheta) * pow((flexTheta - EXTEND_BOUNDARY) / PI, POWER) * 180.0f; } - if (fabsf(ulnarDeviationTheta) > (PI / 6.0f)) { + + const float ULNAR_BOUNDARY = PI / 6.0f; + if (fabsf(ulnarDeviationTheta) > ULNAR_BOUNDARY) { if (trueTwistTheta > 0.0f) { - fred -= glm::sign(ulnarDeviationTheta) * pow(ulnarDeviationTheta / PI, POWER) * 180.0f; + fred -= glm::sign(ulnarDeviationTheta) * pow(fabsf(ulnarDeviationTheta) - ULNAR_BOUNDARY / PI, POWER) * 180.0f; } else { - fred += glm::sign(ulnarDeviationTheta) * pow(ulnarDeviationTheta / PI, POWER) * 180.0f; + fred += glm::sign(ulnarDeviationTheta) * pow(fabsf(ulnarDeviationTheta) - ULNAR_BOUNDARY/ PI, POWER) * 180.0f; } } */ // remember direction of travel. const float TWIST_DEADZONE = PI / 2.0f; - if (trueTwistTheta < -TWIST_DEADZONE) { - fred += glm::sign(trueTwistTheta) * pow((trueTwistTheta / PI), POWER) * 180.0f + pow(TWIST_DEADZONE / PI, POWER) * 180.0f; - } else { - if (trueTwistTheta > (PI / 2.0f)) { - fred += glm::sign(trueTwistTheta) * pow((trueTwistTheta / PI), POWER) * 180.0f - pow(TWIST_DEADZONE / PI, POWER) * 180.0f; + if (!isLeft) { + if (trueTwistTheta < -TWIST_DEADZONE) { + fred += glm::sign(trueTwistTheta) * pow((fabsf(trueTwistTheta) - TWIST_DEADZONE) / PI, POWER) * 90.0f; + } else { + if (trueTwistTheta > TWIST_DEADZONE) { + fred += glm::sign(trueTwistTheta) * pow((fabsf(trueTwistTheta) - TWIST_DEADZONE) / PI, POWER) * 90.0f; + } } + } else { + if (trueTwistTheta < -TWIST_DEADZONE) { + fred -= glm::sign(trueTwistTheta) * pow((fabsf(trueTwistTheta) - TWIST_DEADZONE) / PI, POWER) * 90.0f; + } else { + if (trueTwistTheta > TWIST_DEADZONE) { + fred -= glm::sign(trueTwistTheta) * pow((fabsf(trueTwistTheta) - TWIST_DEADZONE) / PI, POWER) * 90.0f; + } + } + + } - + /* + if (fred < 70.0f) { + fred = 70.0f; + } + if (fred > 175.0f) { + fred = 175.0f; + } + */ if (isLeft) { fred *= -1.0f; } From 954cac907dfa002317308d30c213860a3be249a8 Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Tue, 12 Feb 2019 15:02:56 -0700 Subject: [PATCH 061/112] Other avatars after update and mod timer when active --- interface/src/avatar/AvatarManager.cpp | 11 +++------- interface/src/avatar/MyAvatar.cpp | 8 +++++++ interface/src/avatar/MyAvatar.h | 2 ++ libraries/animation/src/Flow.cpp | 30 +++++++++++--------------- libraries/animation/src/Flow.h | 1 - 5 files changed, 26 insertions(+), 26 deletions(-) diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index 50e8546979..d2ba7149f2 100755 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -271,14 +271,6 @@ void AvatarManager::updateOtherAvatars(float deltaTime) { if (avatar->getSkeletonModel()->isLoaded()) { // remove the orb if it is there avatar->removeOrb(); - if (avatar->getWorkloadRegion() == workload::Region::R1) { - auto &flow = _myAvatar->getSkeletonModel()->getRig().getFlow(); - for (auto &handJointName : HAND_COLLISION_JOINTS) { - int jointIndex = avatar->getJointIndex(handJointName); - glm::vec3 position = avatar->getJointPosition(jointIndex); - flow.setOthersCollision(avatar->getID(), jointIndex, position); - } - } if (avatar->needsPhysicsUpdate()) { _avatarsToChangeInPhysics.insert(avatar); } @@ -305,6 +297,9 @@ void AvatarManager::updateOtherAvatars(float deltaTime) { avatar->setIsNewAvatar(false); } avatar->simulate(deltaTime, inView); + if (avatar->getSkeletonModel()->isLoaded() && avatar->getWorkloadRegion() == workload::Region::R1) { + _myAvatar->addAvatarHandsToFlow(avatar); + } avatar->updateRenderItem(renderTransaction); avatar->updateSpaceProxy(workloadTransaction); avatar->setLastRenderUpdateTime(startTime); diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 92d9270d20..d5f8f8a3ec 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -5312,3 +5312,11 @@ void MyAvatar::releaseGrab(const QUuid& grabID) { } } +void MyAvatar::addAvatarHandsToFlow(const std::shared_ptr& otherAvatar) { + auto &flow = _skeletonModel->getRig().getFlow(); + for (auto &handJointName : HAND_COLLISION_JOINTS) { + int jointIndex = otherAvatar->getJointIndex(handJointName); + glm::vec3 position = otherAvatar->getJointPosition(jointIndex); + flow.setOthersCollision(otherAvatar->getID(), jointIndex, position); + } +} diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 0d27988543..996abcabf2 100755 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -1182,6 +1182,8 @@ public: void updateAvatarEntity(const QUuid& entityID, const QByteArray& entityData) override; void avatarEntityDataToJson(QJsonObject& root) const override; int sendAvatarDataPacket(bool sendAll = false) override; + + void addAvatarHandsToFlow(const std::shared_ptr& otherAvatar); public slots: diff --git a/libraries/animation/src/Flow.cpp b/libraries/animation/src/Flow.cpp index 87d7155abd..8aee4dc53c 100644 --- a/libraries/animation/src/Flow.cpp +++ b/libraries/animation/src/Flow.cpp @@ -461,7 +461,6 @@ void Flow::calculateConstraints() { auto simPrefix = SIM_JOINT_PREFIX.toUpper(); auto skeleton = _rig->getAnimSkeleton(); std::vector handsIndices; - _collisionSystem.resetCollisions(); if (skeleton) { for (int i = 0; i < skeleton->getNumJoints(); i++) { auto name = skeleton->getJointName(i); @@ -517,10 +516,6 @@ void Flow::calculateConstraints() { _collisionSystem.addCollisionSphere(i, PRESET_COLLISION_DATA.at(name)); } } - if (isFlowJoint || isSimJoint) { - auto jointInfo = FlowJointInfo(i, parentIndex, -1, name); - _flowJointInfos.push_back(jointInfo); - } } } @@ -604,7 +599,9 @@ void Flow::cleanUp() { _flowJointData.clear(); _jointThreads.clear(); _flowJointKeywords.clear(); - _flowJointInfos.clear(); + _collisionSystem.resetCollisions(); + _initialized = false; + _active = false; } void Flow::setTransform(float scale, const glm::vec3& position, const glm::quat& rotation) { @@ -619,9 +616,9 @@ void Flow::setTransform(float scale, const glm::vec3& position, const glm::quat& } void Flow::update() { - QElapsedTimer _timer; - _timer.start(); if (_initialized && _active) { + QElapsedTimer _timer; + _timer.start(); updateJoints(); int count = 0; for (auto &thread : _jointThreads) { @@ -633,15 +630,14 @@ void Flow::update() { thread.apply(); } setJoints(); - } - _deltaTime += _timer.nsecsElapsed(); - _updates++; - if (_deltaTime > _deltaTimeLimit) { - qDebug() << "Flow C++ update " << _deltaTime / _updates << " nanoSeconds"; - _deltaTime = 0; - _updates = 0; - } - + _deltaTime += _timer.nsecsElapsed(); + _updates++; + if (_deltaTime > _deltaTimeLimit) { + qDebug() << "Flow C++ update " << _deltaTime / _updates << " nanoSeconds"; + _deltaTime = 0; + _updates = 0; + } + } } bool Flow::worldToJointPoint(const glm::vec3& position, const int jointIndex, glm::vec3& jointSpacePosition) const { diff --git a/libraries/animation/src/Flow.h b/libraries/animation/src/Flow.h index ec98b32265..9c088bf263 100644 --- a/libraries/animation/src/Flow.h +++ b/libraries/animation/src/Flow.h @@ -296,7 +296,6 @@ private: std::map _flowJointData; std::vector _jointThreads; std::vector _flowJointKeywords; - std::vector _flowJointInfos; FlowCollisionSystem _collisionSystem; bool _initialized { false }; bool _active { false }; From 9baed717f9afa5efd92110e3067b690ca98c89d0 Mon Sep 17 00:00:00 2001 From: amantley Date: Tue, 12 Feb 2019 17:55:12 -0800 Subject: [PATCH 062/112] integrated flex, ulnar and twist behaviour to pole vector theta computation --- .../src/AnimPoleVectorConstraint.cpp | 173 +++++++++++++----- .../animation/src/AnimPoleVectorConstraint.h | 5 + 2 files changed, 133 insertions(+), 45 deletions(-) diff --git a/libraries/animation/src/AnimPoleVectorConstraint.cpp b/libraries/animation/src/AnimPoleVectorConstraint.cpp index b50f6dc280..590750961e 100644 --- a/libraries/animation/src/AnimPoleVectorConstraint.cpp +++ b/libraries/animation/src/AnimPoleVectorConstraint.cpp @@ -249,23 +249,51 @@ const AnimPoseVec& AnimPoleVectorConstraint::evaluate(const AnimVariantMap& anim } fred = findThetaNewWay(tipPose.trans(), basePose.trans(), isLeft); + glm::quat relativeHandRotation = (midPose.inverse() * tipPose).rot(); + + relativeHandRotation = glm::normalize(relativeHandRotation); + if (relativeHandRotation.w < 0.0f) { + relativeHandRotation.x *= -1.0f; + relativeHandRotation.y *= -1.0f; + relativeHandRotation.z *= -1.0f; + relativeHandRotation.w *= -1.0f; + } + + glm::quat twist; + glm::quat ulnarDeviation; + //swingTwistDecomposition(twistUlnarSwing, Vectors::UNIT_Z, twist, ulnarDeviation); + swingTwistDecomposition(relativeHandRotation, Vectors::UNIT_Z, twist, ulnarDeviation); + + if (ulnarDeviation.w < 0.0f) { + ulnarDeviation.x *= -1.0f; + ulnarDeviation.y *= -1.0f; + ulnarDeviation.z *= -1.0f; + ulnarDeviation.w *= -1.0f; + } + //glm::vec3 twistAxis = glm::axis(twist); + glm::vec3 ulnarAxis = glm::axis(ulnarDeviation); + //float twistTheta = glm::sign(twistAxis[1]) * glm::angle(twist); + float ulnarDeviationTheta = glm::sign(ulnarAxis[2]) * glm::angle(ulnarDeviation); + _ulnarRadialThetaRunningAverage = 0.5f * _ulnarRadialThetaRunningAverage + 0.5f * ulnarDeviationTheta; + //get the swingTwist of the hand to lower arm glm::quat flex; glm::quat twistUlnarSwing; - glm::quat relativeHandRotation = (midPose.inverse() * tipPose).rot(); - swingTwistDecomposition(relativeHandRotation, Vectors::UNIT_X, twistUlnarSwing, flex); + + swingTwistDecomposition(twist, Vectors::UNIT_X, twistUlnarSwing, flex); + if (flex.w < 0.0f) { + flex.x *= -1.0f; + flex.y *= -1.0f; + flex.z *= -1.0f; + flex.w *= -1.0f; + } + glm::vec3 flexAxis = glm::axis(flex); - + //float swingTheta = glm::angle(twistUlnarSwing); float flexTheta = glm::sign(flexAxis[0]) * glm::angle(flex); - glm::quat twist; - glm::quat ulnarDeviation; - swingTwistDecomposition(twistUlnarSwing, Vectors::UNIT_Z, twist, ulnarDeviation); - - glm::vec3 twistAxis = glm::axis(twist); - glm::vec3 ulnarAxis = glm::axis(ulnarDeviation); - float twistTheta = glm::sign(twistAxis[1]) * glm::angle(twist); - float ulnarDeviationTheta = glm::sign(ulnarAxis[2]) * glm::angle(ulnarDeviation); + _flexThetaRunningAverage = 0.5f * _flexThetaRunningAverage + 0.5f * flexTheta; + glm::quat trueTwist; glm::quat nonTwist; @@ -279,6 +307,12 @@ const AnimPoseVec& AnimPoleVectorConstraint::evaluate(const AnimVariantMap& anim glm::vec3 trueTwistAxis = glm::axis(trueTwist); float trueTwistTheta = glm::angle(trueTwist); trueTwistTheta *= glm::sign(trueTwistAxis[1]) * glm::angle(trueTwist); + _twistThetaRunningAverage = 0.5f * _twistThetaRunningAverage + 0.5f * trueTwistTheta; + + + + + //while (trueTwistTheta > PI) { // trueTwistTheta -= 2.0f * PI; //} @@ -286,11 +320,11 @@ const AnimPoseVec& AnimPoleVectorConstraint::evaluate(const AnimVariantMap& anim // glm::vec3 eulerVersion = glm::eulerAngles(relativeHandRotation); if (!isLeft) { - //qCDebug(animation) << "flex: " << (flexTheta / PI) * 180.0f << " twist: " << (twistTheta / PI) * 180.0f << " ulnar deviation: " << (ulnarDeviationTheta / PI) * 180.0f; - qCDebug(animation) << "trueTwist: " << (trueTwistTheta / PI) * 180.0f;// << " old twist: " << (twistTheta / PI) * 180.0f; + qCDebug(animation) << "flex: " << (flexTheta / PI) * 180.0f << " twist: " << (trueTwistTheta / PI) * 180.0f << " ulnar deviation: " << (ulnarDeviationTheta / PI) * 180.0f; + //qCDebug(animation) << "trueTwist: " << (trueTwistTheta / PI) * 180.0f;// << " old twist: " << (twistTheta / PI) * 180.0f; //qCDebug(animation) << "ulnarAxis " << flexUlnarAxis; - qCDebug(animation) << "relative hand rotation " << relativeHandRotation; - qCDebug(animation) << "twist rotation " << trueTwist; + // qCDebug(animation) << "relative hand rotation " << relativeHandRotation; + // qCDebug(animation) << "twist rotation " << trueTwist; //QString name = QString("handMarker3"); //const vec4 WHITE(1.0f); @@ -308,38 +342,88 @@ const AnimPoseVec& AnimPoleVectorConstraint::evaluate(const AnimVariantMap& anim deltaThetaUlnar = correctElbowForHandUlnarRadialDeviation(tipPose, midPose); } + if (isLeft) { + fred *= -1.0f; + } + // make the dead zone PI/6.0 const float POWER = 2.0f; - const float FLEX_BOUNDARY = PI / 2.0f; - const float EXTEND_BOUNDARY = -PI / 4.0f; - /* - if (flexTheta > FLEX_BOUNDARY) { - fred -= glm::sign(flexTheta) * pow((flexTheta - FLEX_BOUNDARY) / PI, POWER) * 180.0f; - } else if (flexTheta < EXTEND_BOUNDARY) { - fred -= glm::sign(flexTheta) * pow((flexTheta - EXTEND_BOUNDARY) / PI, POWER) * 180.0f; - } - - const float ULNAR_BOUNDARY = PI / 6.0f; - if (fabsf(ulnarDeviationTheta) > ULNAR_BOUNDARY) { - if (trueTwistTheta > 0.0f) { - fred -= glm::sign(ulnarDeviationTheta) * pow(fabsf(ulnarDeviationTheta) - ULNAR_BOUNDARY / PI, POWER) * 180.0f; - } else { - fred += glm::sign(ulnarDeviationTheta) * pow(fabsf(ulnarDeviationTheta) - ULNAR_BOUNDARY/ PI, POWER) * 180.0f; - } - } - */ - // remember direction of travel. - const float TWIST_DEADZONE = PI / 2.0f; - if (!isLeft) { - if (trueTwistTheta < -TWIST_DEADZONE) { - fred += glm::sign(trueTwistTheta) * pow((fabsf(trueTwistTheta) - TWIST_DEADZONE) / PI, POWER) * 90.0f; - } else { - if (trueTwistTheta > TWIST_DEADZONE) { - fred += glm::sign(trueTwistTheta) * pow((fabsf(trueTwistTheta) - TWIST_DEADZONE) / PI, POWER) * 90.0f; + const float FLEX_BOUNDARY = PI / 4.0f; + const float EXTEND_BOUNDARY = -PI / 6.0f; + float flexCorrection = 0.0f; + if (isLeft) { + if (_flexThetaRunningAverage > FLEX_BOUNDARY) { + flexCorrection = ((_flexThetaRunningAverage - FLEX_BOUNDARY) / PI) * 180.0f; // glm::sign(flexTheta) * pow((flexTheta - FLEX_BOUNDARY) / PI, POWER) * 180.0f; + if (flexCorrection > 30.0f) { + flexCorrection = 30.0f; } + } else if (_flexThetaRunningAverage < EXTEND_BOUNDARY) { + flexCorrection = ((_flexThetaRunningAverage - EXTEND_BOUNDARY) / PI) * 180.0f; // glm::sign(flexTheta) * pow((flexTheta - EXTEND_BOUNDARY) / PI, POWER) * 180.0f; } + fred += flexCorrection; } else { + if (_flexThetaRunningAverage > FLEX_BOUNDARY) { + flexCorrection = ((_flexThetaRunningAverage - FLEX_BOUNDARY) / PI) * 180.0f; // glm::sign(flexTheta) * pow((flexTheta - FLEX_BOUNDARY) / PI, POWER) * 180.0f; + if (flexCorrection > 30.0f) { + flexCorrection = 30.0f; + } + } else if (_flexThetaRunningAverage < EXTEND_BOUNDARY) { + flexCorrection = ((_flexThetaRunningAverage - EXTEND_BOUNDARY) / PI) * 180.0f; // glm::sign(flexTheta) * pow((flexTheta - EXTEND_BOUNDARY) / PI, POWER) * 180.0f; + } + fred -= flexCorrection; + } + + const float TWIST_ULNAR_DEADZONE = 0.0f; + const float ULNAR_BOUNDARY = PI / 12.0f; + if (fabsf(_ulnarRadialThetaRunningAverage) > ULNAR_BOUNDARY) { + if (fabs(_twistThetaRunningAverage) > TWIST_ULNAR_DEADZONE) { + float twistCoefficient = pow((fabs(_twistThetaRunningAverage) - TWIST_ULNAR_DEADZONE) / (PI / 20.0f), POWER); + float ulnarCorrection = 0.0f; + if (isLeft) { + if (trueTwistTheta < 0.0f) { + ulnarCorrection -= glm::sign(_ulnarRadialThetaRunningAverage) * pow((fabsf(_ulnarRadialThetaRunningAverage) - ULNAR_BOUNDARY) / PI, POWER) * 80.0f * twistCoefficient; + } else { + ulnarCorrection += glm::sign(_ulnarRadialThetaRunningAverage) * pow((fabsf(_ulnarRadialThetaRunningAverage) - ULNAR_BOUNDARY) / PI, POWER) * 80.0f * twistCoefficient; + } + } else { + // right hand + if (trueTwistTheta > 0.0f) { + ulnarCorrection -= glm::sign(_ulnarRadialThetaRunningAverage) * pow((fabsf(_ulnarRadialThetaRunningAverage) - ULNAR_BOUNDARY) / PI, POWER) * 80.0f * twistCoefficient; + } else { + ulnarCorrection += glm::sign(_ulnarRadialThetaRunningAverage) * pow((fabsf(_ulnarRadialThetaRunningAverage) - ULNAR_BOUNDARY) / PI, POWER) * 80.0f * twistCoefficient; + } + + } + if (fabsf(ulnarCorrection) > 20.0f) { + ulnarCorrection = glm::sign(ulnarCorrection) * 20.0f; + } + fred += ulnarCorrection; + } + } + + // remember direction of travel. + const float TWIST_DEADZONE = (4.0f * PI) / 9.0f; + //if (!isLeft) { + float twistCorrection = 0.0f; + if (_twistThetaRunningAverage < -TWIST_DEADZONE) { + twistCorrection = glm::sign(_twistThetaRunningAverage) * pow((fabsf(_twistThetaRunningAverage) - TWIST_DEADZONE) / PI, POWER) * 80.0f; + } else { + if (_twistThetaRunningAverage > TWIST_DEADZONE) { + twistCorrection = glm::sign(_twistThetaRunningAverage) * pow((fabsf(_twistThetaRunningAverage) - TWIST_DEADZONE) / PI, POWER) * 80.0f; + } + } + if (fabsf(twistCorrection) > 45.0f) { + fred += glm::sign(twistCorrection) * 45.0f; + } else { + fred += twistCorrection; + } + + _lastTheta = 0.5f * _lastTheta + 0.5f * fred; + + //} + + /*else { if (trueTwistTheta < -TWIST_DEADZONE) { fred -= glm::sign(trueTwistTheta) * pow((fabsf(trueTwistTheta) - TWIST_DEADZONE) / PI, POWER) * 90.0f; } else { @@ -350,6 +434,7 @@ const AnimPoseVec& AnimPoleVectorConstraint::evaluate(const AnimVariantMap& anim } + */ /* if (fred < 70.0f) { fred = 70.0f; @@ -358,10 +443,8 @@ const AnimPoseVec& AnimPoleVectorConstraint::evaluate(const AnimVariantMap& anim fred = 175.0f; } */ - if (isLeft) { - fred *= -1.0f; - } - theta = ((180.0f - fred) / 180.0f)*PI; + + theta = ((180.0f - _lastTheta) / 180.0f)*PI; //qCDebug(animation) << "the wrist correction theta is -----> " << isLeft << " theta: " << deltaTheta; diff --git a/libraries/animation/src/AnimPoleVectorConstraint.h b/libraries/animation/src/AnimPoleVectorConstraint.h index be3346974e..078676d4f9 100644 --- a/libraries/animation/src/AnimPoleVectorConstraint.h +++ b/libraries/animation/src/AnimPoleVectorConstraint.h @@ -66,6 +66,11 @@ protected: float _interpAlphaVel { 0.0f }; float _interpAlpha { 0.0f }; + float _twistThetaRunningAverage { 0.0f }; + float _flexThetaRunningAverage { 0.0f }; + float _ulnarRadialThetaRunningAverage { 0.0f }; + float _lastTheta { 0.0f }; + AnimChain _snapshotChain; // no copies From bebbbc643b46132b1aacce363e3c66b3942197fb Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Wed, 13 Feb 2019 06:27:49 -0700 Subject: [PATCH 063/112] add deltaTime to simulation --- libraries/animation/src/Flow.cpp | 43 ++++++++++++++++++-------------- libraries/animation/src/Flow.h | 13 +++++----- libraries/animation/src/Rig.cpp | 5 ++-- 3 files changed, 33 insertions(+), 28 deletions(-) diff --git a/libraries/animation/src/Flow.cpp b/libraries/animation/src/Flow.cpp index 8aee4dc53c..ec17a56a4a 100644 --- a/libraries/animation/src/Flow.cpp +++ b/libraries/animation/src/Flow.cpp @@ -206,22 +206,26 @@ void FlowCollisionSystem::prepareCollisions() { _othersCollisions.clear(); } -void FlowNode::update(const glm::vec3& accelerationOffset) { +void FlowNode::update(float deltaTime, const glm::vec3& accelerationOffset) { _acceleration = glm::vec3(0.0f, _settings._gravity, 0.0f); _previousVelocity = _currentVelocity; _currentVelocity = _currentPosition - _previousPosition; _previousPosition = _currentPosition; if (!_anchored) { // Add inertia + const float FPS = 60.0f; + float timeRatio = (FPS * deltaTime); + auto deltaVelocity = _previousVelocity - _currentVelocity; auto centrifugeVector = glm::length(deltaVelocity) != 0.0f ? glm::normalize(deltaVelocity) : glm::vec3(); - _acceleration = _acceleration + centrifugeVector * _settings._inertia * glm::length(_currentVelocity); + _acceleration = _acceleration + centrifugeVector * _settings._inertia * glm::length(_currentVelocity) * (1 / timeRatio); // Add offset _acceleration += accelerationOffset; - // Calculate new position - _currentPosition = (_currentPosition + _currentVelocity * _settings._damping) + - (_acceleration * glm::pow(_settings._delta * _scale, 2)); + + glm::vec3 deltaAcceleration = timeRatio * _acceleration * glm::pow(_settings._delta * _scale, 2); + // Calculate new position + _currentPosition = (_currentPosition + _currentVelocity * _settings._damping) + deltaAcceleration; } else { _acceleration = glm::vec3(0.0f); @@ -289,13 +293,13 @@ void FlowJoint::setRecoveryPosition(const glm::vec3& recoveryPosition) { _applyRecovery = true; } -void FlowJoint::update() { +void FlowJoint::update(float deltaTime) { glm::vec3 accelerationOffset = glm::vec3(0.0f); if (_node._settings._stiffness > 0.0f) { glm::vec3 recoveryVector = _recoveryPosition - _node._currentPosition; accelerationOffset = recoveryVector * glm::pow(_node._settings._stiffness, 3); } - _node.update(accelerationOffset); + _node.update(deltaTime, accelerationOffset); if (_node._anchored) { if (!_isDummy) { _node._currentPosition = _updatedPosition; @@ -368,14 +372,14 @@ void FlowThread::computeRecovery() { } }; -void FlowThread::update() { +void FlowThread::update(float deltaTime) { if (getActive()) { _positions.clear(); _radius = _jointsPointer->at(_joints[0])._node._settings._radius; computeRecovery(); for (size_t i = 0; i < _joints.size(); i++) { auto &joint = _jointsPointer->at(_joints[i]); - joint.update(); + joint.update(deltaTime); _positions.push_back(joint._node._currentPosition); } } @@ -447,10 +451,6 @@ bool FlowThread::getActive() { return _jointsPointer->at(_joints[0])._node._active; }; -void Flow::setRig(Rig* rig) { - _rig = rig; -}; - void Flow::calculateConstraints() { cleanUp(); if (!_rig) { @@ -593,6 +593,9 @@ void Flow::calculateConstraints() { } } _initialized = _jointThreads.size() > 0; + if (_initialized) { + _mtimer.restart(); + } } void Flow::cleanUp() { @@ -615,14 +618,14 @@ void Flow::setTransform(float scale, const glm::vec3& position, const glm::quat& _active = true; } -void Flow::update() { +void Flow::update(float deltaTime) { if (_initialized && _active) { - QElapsedTimer _timer; - _timer.start(); + QElapsedTimer timer; + timer.start(); updateJoints(); int count = 0; for (auto &thread : _jointThreads) { - thread.update(); + thread.update(deltaTime); thread.solve(USE_COLLISIONS, _collisionSystem); if (!updateRootFramePositions(count++)) { return; @@ -630,10 +633,12 @@ void Flow::update() { thread.apply(); } setJoints(); - _deltaTime += _timer.nsecsElapsed(); + _deltaTime += timer.nsecsElapsed(); _updates++; if (_deltaTime > _deltaTimeLimit) { - qDebug() << "Flow C++ update " << _deltaTime / _updates << " nanoSeconds"; + qint64 currentTime = _mtimer.elapsed(); + qDebug() << "Flow C++ update " << _deltaTime / _updates << " nanoSeconds " << (currentTime - _lastTime) / _updates << " miliseconds since last update"; + _lastTime = currentTime; _deltaTime = 0; _updates = 0; } diff --git a/libraries/animation/src/Flow.h b/libraries/animation/src/Flow.h index 9c088bf263..ff21d4a776 100644 --- a/libraries/animation/src/Flow.h +++ b/libraries/animation/src/Flow.h @@ -199,7 +199,7 @@ public: bool _colliding { false }; bool _active { true }; - void update(const glm::vec3& accelerationOffset); + void update(float deltaTime, const glm::vec3& accelerationOffset); void solve(const glm::vec3& constrainPoint, float maxDistance, const FlowCollisionResult& collision); void solveConstraints(const glm::vec3& constrainPoint, float maxDistance); void solveCollisions(const FlowCollisionResult& collision); @@ -212,7 +212,7 @@ public: void setInitialData(const glm::vec3& initialPosition, const glm::vec3& initialTranslation, const glm::quat& initialRotation, const glm::vec3& parentPosition); void setUpdatedData(const glm::vec3& updatedPosition, const glm::vec3& updatedTranslation, const glm::quat& updatedRotation, const glm::vec3& parentPosition, const glm::quat& parentWorldRotation); void setRecoveryPosition(const glm::vec3& recoveryPosition); - void update(); + void update(float deltaTime); void solve(const FlowCollisionResult& collision); int _index{ -1 }; @@ -257,7 +257,7 @@ public: void resetLength(); void computeFlowThread(int rootIndex); void computeRecovery(); - void update(); + void update(float deltaTime); void solve(bool useCollisions, FlowCollisionSystem& collisionSystem); void computeJointRotations(); void apply(); @@ -274,10 +274,9 @@ public: class Flow { public: - Flow() {}; - void setRig(Rig* rig); + Flow(Rig* rig) { _rig = rig; }; void calculateConstraints(); - void update(); + void update(float deltaTime); void setTransform(float scale, const glm::vec3& position, const glm::quat& rotation); const std::map& getJoints() const { return _flowJointData; } const std::vector& getThreads() const { return _jointThreads; } @@ -302,6 +301,8 @@ private: int _deltaTime { 0 }; int _deltaTimeLimit { 4000000 }; int _updates { 0 }; + QElapsedTimer _mtimer; + long _lastTime { 0 }; }; #endif // hifi_Flow_h diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index 5042c00be6..e6e4f74c11 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -75,7 +75,7 @@ static const QString MAIN_STATE_MACHINE_RIGHT_FOOT_ROTATION("mainStateMachineRig static const QString MAIN_STATE_MACHINE_RIGHT_FOOT_POSITION("mainStateMachineRightFootPosition"); -Rig::Rig() { +Rig::Rig() : _flow(this) { // Ensure thread-safe access to the rigRegistry. std::lock_guard guard(rigRegistryMutex); @@ -1217,7 +1217,7 @@ void Rig::updateAnimations(float deltaTime, const glm::mat4& rootTransform, cons buildAbsoluteRigPoses(_internalPoseSet._relativePoses, _internalPoseSet._absolutePoses); buildAbsoluteRigPoses(_networkPoseSet._relativePoses, _networkPoseSet._absolutePoses); // copy internal poses to external poses - _flow.update(); + _flow.update(deltaTime); { QWriteLocker writeLock(&_externalPoseSetLock); @@ -1873,7 +1873,6 @@ void Rig::initAnimGraph(const QUrl& url) { auto roleState = roleAnimState.second; overrideRoleAnimation(roleState.role, roleState.url, roleState.fps, roleState.loop, roleState.firstFrame, roleState.lastFrame); } - _flow.setRig(this); emit onLoadComplete(); }); connect(_animLoader.get(), &AnimNodeLoader::error, [url](int error, QString str) { From 05d50f32ba974a7700cbc5bdc0c15b5cee7691a6 Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Wed, 13 Feb 2019 08:16:22 -0700 Subject: [PATCH 064/112] time budget --- libraries/animation/src/Flow.cpp | 27 ++++++++++++++------------- libraries/animation/src/Flow.h | 7 ++++--- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/libraries/animation/src/Flow.cpp b/libraries/animation/src/Flow.cpp index ec17a56a4a..ab22e25326 100644 --- a/libraries/animation/src/Flow.cpp +++ b/libraries/animation/src/Flow.cpp @@ -593,9 +593,6 @@ void Flow::calculateConstraints() { } } _initialized = _jointThreads.size() > 0; - if (_initialized) { - _mtimer.restart(); - } } void Flow::cleanUp() { @@ -620,25 +617,29 @@ void Flow::setTransform(float scale, const glm::vec3& position, const glm::quat& void Flow::update(float deltaTime) { if (_initialized && _active) { - QElapsedTimer timer; - timer.start(); + QElapsedTimer _timer; + _timer.start(); updateJoints(); - int count = 0; - for (auto &thread : _jointThreads) { + for (size_t i = 0; i < _jointThreads.size(); i++) { + size_t index = _invertThreadLoop ? _jointThreads.size() - 1 - i : i; + auto &thread = _jointThreads[index]; thread.update(deltaTime); thread.solve(USE_COLLISIONS, _collisionSystem); - if (!updateRootFramePositions(count++)) { + if (!updateRootFramePositions(index)) { return; } thread.apply(); + if (_timer.elapsed() > MAX_UPDATE_FLOW_TIME_BUDGET) { + break; + qWarning(animation) << "Flow Bones ran out of time updating threads"; + } } setJoints(); - _deltaTime += timer.nsecsElapsed(); + _invertThreadLoop = !_invertThreadLoop; + _deltaTime += _timer.nsecsElapsed(); _updates++; if (_deltaTime > _deltaTimeLimit) { - qint64 currentTime = _mtimer.elapsed(); - qDebug() << "Flow C++ update " << _deltaTime / _updates << " nanoSeconds " << (currentTime - _lastTime) / _updates << " miliseconds since last update"; - _lastTime = currentTime; + qDebug() << "Flow C++ update " << _deltaTime / _updates << " nanoSeconds "; _deltaTime = 0; _updates = 0; } @@ -656,7 +657,7 @@ bool Flow::worldToJointPoint(const glm::vec3& position, const int jointIndex, gl return false; } -bool Flow::updateRootFramePositions(int threadIndex) { +bool Flow::updateRootFramePositions(size_t threadIndex) { auto &joints = _jointThreads[threadIndex]._joints; int rootIndex = _flowJointData[joints[0]]._parentIndex; _jointThreads[threadIndex]._rootFramePositions.clear(); diff --git a/libraries/animation/src/Flow.h b/libraries/animation/src/Flow.h index ff21d4a776..a06f785da2 100644 --- a/libraries/animation/src/Flow.h +++ b/libraries/animation/src/Flow.h @@ -62,6 +62,8 @@ const float DEFAULT_INERTIA = 0.8f; const float DEFAULT_DELTA = 0.55f; const float DEFAULT_RADIUS = 0.01f; +const uint64_t MAX_UPDATE_FLOW_TIME_BUDGET = 2000; + struct FlowPhysicsSettings { FlowPhysicsSettings() {}; FlowPhysicsSettings(bool active, float stiffness, float gravity, float damping, float inertia, float delta, float radius) { @@ -286,7 +288,7 @@ private: void setJoints(); void cleanUp(); void updateJoints(); - bool updateRootFramePositions(int threadIndex); + bool updateRootFramePositions(size_t threadIndex); bool worldToJointPoint(const glm::vec3& position, const int jointIndex, glm::vec3& jointSpacePosition) const; Rig* _rig; float _scale { 1.0f }; @@ -301,8 +303,7 @@ private: int _deltaTime { 0 }; int _deltaTimeLimit { 4000000 }; int _updates { 0 }; - QElapsedTimer _mtimer; - long _lastTime { 0 }; + bool _invertThreadLoop { false }; }; #endif // hifi_Flow_h From c6da7cc41df6c86eb5596dd8df7288365c34da36 Mon Sep 17 00:00:00 2001 From: amantley Date: Wed, 13 Feb 2019 17:12:28 -0800 Subject: [PATCH 065/112] everything looks pretty good now but need to move the code to rig and need to get rig of wrap around problem with the twist decomp --- .../src/AnimPoleVectorConstraint.cpp | 82 ++++++++++++------- 1 file changed, 52 insertions(+), 30 deletions(-) diff --git a/libraries/animation/src/AnimPoleVectorConstraint.cpp b/libraries/animation/src/AnimPoleVectorConstraint.cpp index 590750961e..bf246cf51a 100644 --- a/libraries/animation/src/AnimPoleVectorConstraint.cpp +++ b/libraries/animation/src/AnimPoleVectorConstraint.cpp @@ -131,11 +131,13 @@ float AnimPoleVectorConstraint::findThetaNewWay(const glm::vec3& hand, const glm initial_valuesZ = zWeightBottom * glm::max(zStart - (armToHand[2] / defaultArmLength), 0.0f) * fabs(armToHand[1] / defaultArmLength); } + //1.0f + armToHand[1]/defaultArmLength + float initial_valuesX; if (left) { initial_valuesX = weights[0] * glm::max(-1.0f * (armToHand[0] / defaultArmLength) + xStart, 0.0f); } else { - initial_valuesX = weights[0] * ((armToHand[0] / defaultArmLength) + xStart); + initial_valuesX = weights[0] * (((armToHand[0] / defaultArmLength) + xStart) - (0.3f) * ((1.0f + (armToHand[1] / defaultArmLength))/2.0f)); } float theta = initial_valuesX + initial_valuesY + initial_valuesZ; @@ -264,6 +266,7 @@ const AnimPoseVec& AnimPoleVectorConstraint::evaluate(const AnimVariantMap& anim //swingTwistDecomposition(twistUlnarSwing, Vectors::UNIT_Z, twist, ulnarDeviation); swingTwistDecomposition(relativeHandRotation, Vectors::UNIT_Z, twist, ulnarDeviation); + ulnarDeviation = glm::normalize(ulnarDeviation); if (ulnarDeviation.w < 0.0f) { ulnarDeviation.x *= -1.0f; ulnarDeviation.y *= -1.0f; @@ -280,7 +283,9 @@ const AnimPoseVec& AnimPoleVectorConstraint::evaluate(const AnimVariantMap& anim glm::quat flex; glm::quat twistUlnarSwing; - swingTwistDecomposition(twist, Vectors::UNIT_X, twistUlnarSwing, flex); + swingTwistDecomposition(relativeHandRotation, Vectors::UNIT_X, twistUlnarSwing, flex); + + flex = glm::normalize(flex); if (flex.w < 0.0f) { flex.x *= -1.0f; flex.y *= -1.0f; @@ -298,6 +303,7 @@ const AnimPoseVec& AnimPoleVectorConstraint::evaluate(const AnimVariantMap& anim glm::quat trueTwist; glm::quat nonTwist; swingTwistDecomposition(relativeHandRotation, Vectors::UNIT_Y, nonTwist, trueTwist); + trueTwist = glm::normalize(trueTwist); if (trueTwist.w < 0.0f) { trueTwist.x *= -1.0f; trueTwist.y *= -1.0f; @@ -320,6 +326,7 @@ const AnimPoseVec& AnimPoleVectorConstraint::evaluate(const AnimVariantMap& anim // glm::vec3 eulerVersion = glm::eulerAngles(relativeHandRotation); if (!isLeft) { + qCDebug(animation) << "flex ave: " << (_flexThetaRunningAverage / PI) * 180.0f << " twist ave: " << (_twistThetaRunningAverage / PI) * 180.0f << " ulnar deviation ave: " << (_ulnarRadialThetaRunningAverage / PI) * 180.0f; qCDebug(animation) << "flex: " << (flexTheta / PI) * 180.0f << " twist: " << (trueTwistTheta / PI) * 180.0f << " ulnar deviation: " << (ulnarDeviationTheta / PI) * 180.0f; //qCDebug(animation) << "trueTwist: " << (trueTwistTheta / PI) * 180.0f;// << " old twist: " << (twistTheta / PI) * 180.0f; //qCDebug(animation) << "ulnarAxis " << flexUlnarAxis; @@ -350,48 +357,59 @@ const AnimPoseVec& AnimPoleVectorConstraint::evaluate(const AnimVariantMap& anim const float POWER = 2.0f; const float FLEX_BOUNDARY = PI / 4.0f; - const float EXTEND_BOUNDARY = -PI / 6.0f; + const float EXTEND_BOUNDARY = -PI / 5.0f; float flexCorrection = 0.0f; if (isLeft) { if (_flexThetaRunningAverage > FLEX_BOUNDARY) { - flexCorrection = ((_flexThetaRunningAverage - FLEX_BOUNDARY) / PI) * 180.0f; // glm::sign(flexTheta) * pow((flexTheta - FLEX_BOUNDARY) / PI, POWER) * 180.0f; - if (flexCorrection > 30.0f) { - flexCorrection = 30.0f; - } + flexCorrection = ((_flexThetaRunningAverage - FLEX_BOUNDARY) / PI) * 90.0f; // glm::sign(flexTheta) * pow((flexTheta - FLEX_BOUNDARY) / PI, POWER) * 180.0f; } else if (_flexThetaRunningAverage < EXTEND_BOUNDARY) { - flexCorrection = ((_flexThetaRunningAverage - EXTEND_BOUNDARY) / PI) * 180.0f; // glm::sign(flexTheta) * pow((flexTheta - EXTEND_BOUNDARY) / PI, POWER) * 180.0f; + flexCorrection = ((_flexThetaRunningAverage - EXTEND_BOUNDARY) / PI) * 90.0f; // glm::sign(flexTheta) * pow((flexTheta - EXTEND_BOUNDARY) / PI, POWER) * 180.0f; + } + if (fabs(flexCorrection) > 30.0f) { + flexCorrection = glm::sign(flexCorrection) * 30.0f; } fred += flexCorrection; } else { if (_flexThetaRunningAverage > FLEX_BOUNDARY) { flexCorrection = ((_flexThetaRunningAverage - FLEX_BOUNDARY) / PI) * 180.0f; // glm::sign(flexTheta) * pow((flexTheta - FLEX_BOUNDARY) / PI, POWER) * 180.0f; - if (flexCorrection > 30.0f) { - flexCorrection = 30.0f; - } } else if (_flexThetaRunningAverage < EXTEND_BOUNDARY) { flexCorrection = ((_flexThetaRunningAverage - EXTEND_BOUNDARY) / PI) * 180.0f; // glm::sign(flexTheta) * pow((flexTheta - EXTEND_BOUNDARY) / PI, POWER) * 180.0f; } + if (fabs(flexCorrection) > 30.0f) { + flexCorrection = glm::sign(flexCorrection) * 30.0f; + } fred -= flexCorrection; } const float TWIST_ULNAR_DEADZONE = 0.0f; - const float ULNAR_BOUNDARY = PI / 12.0f; - if (fabsf(_ulnarRadialThetaRunningAverage) > ULNAR_BOUNDARY) { + const float ULNAR_BOUNDARY_MINUS = -PI / 12.0f; + const float ULNAR_BOUNDARY_PLUS = PI / 24.0f; + float ulnarDiff = 0.0f; + float ulnarCorrection = 0.0f; + if (_ulnarRadialThetaRunningAverage > ULNAR_BOUNDARY_PLUS) { + ulnarDiff = _ulnarRadialThetaRunningAverage - ULNAR_BOUNDARY_PLUS; + } else if (_ulnarRadialThetaRunningAverage < ULNAR_BOUNDARY_MINUS) { + ulnarDiff = _ulnarRadialThetaRunningAverage - ULNAR_BOUNDARY_MINUS; + } + if(fabs(ulnarDiff) > 0.0f){ if (fabs(_twistThetaRunningAverage) > TWIST_ULNAR_DEADZONE) { - float twistCoefficient = pow((fabs(_twistThetaRunningAverage) - TWIST_ULNAR_DEADZONE) / (PI / 20.0f), POWER); - float ulnarCorrection = 0.0f; + float twistCoefficient = (fabs(_twistThetaRunningAverage) / (PI / 20.0f)); + if (twistCoefficient > 1.0f) { + twistCoefficient = 1.0f; + } + if (isLeft) { if (trueTwistTheta < 0.0f) { - ulnarCorrection -= glm::sign(_ulnarRadialThetaRunningAverage) * pow((fabsf(_ulnarRadialThetaRunningAverage) - ULNAR_BOUNDARY) / PI, POWER) * 80.0f * twistCoefficient; + ulnarCorrection -= glm::sign(ulnarDiff) * (fabs(ulnarDiff) / PI) * 90.0f * twistCoefficient; } else { - ulnarCorrection += glm::sign(_ulnarRadialThetaRunningAverage) * pow((fabsf(_ulnarRadialThetaRunningAverage) - ULNAR_BOUNDARY) / PI, POWER) * 80.0f * twistCoefficient; + ulnarCorrection += glm::sign(ulnarDiff) * (fabs(ulnarDiff) / PI) * 90.0f * twistCoefficient; } } else { // right hand if (trueTwistTheta > 0.0f) { - ulnarCorrection -= glm::sign(_ulnarRadialThetaRunningAverage) * pow((fabsf(_ulnarRadialThetaRunningAverage) - ULNAR_BOUNDARY) / PI, POWER) * 80.0f * twistCoefficient; + ulnarCorrection -= glm::sign(ulnarDiff) * (fabs(ulnarDiff) / PI) * 90.0f * twistCoefficient; } else { - ulnarCorrection += glm::sign(_ulnarRadialThetaRunningAverage) * pow((fabsf(_ulnarRadialThetaRunningAverage) - ULNAR_BOUNDARY) / PI, POWER) * 80.0f * twistCoefficient; + ulnarCorrection += glm::sign(ulnarDiff) * (fabs(ulnarDiff) / PI) * 90.0f * twistCoefficient; } } @@ -403,24 +421,26 @@ const AnimPoseVec& AnimPoleVectorConstraint::evaluate(const AnimVariantMap& anim } // remember direction of travel. - const float TWIST_DEADZONE = (4.0f * PI) / 9.0f; + const float TWIST_DEADZONE = PI / 2.0f; //if (!isLeft) { float twistCorrection = 0.0f; if (_twistThetaRunningAverage < -TWIST_DEADZONE) { - twistCorrection = glm::sign(_twistThetaRunningAverage) * pow((fabsf(_twistThetaRunningAverage) - TWIST_DEADZONE) / PI, POWER) * 80.0f; + twistCorrection = glm::sign(_twistThetaRunningAverage) * ((fabsf(_twistThetaRunningAverage) - TWIST_DEADZONE) / PI) * 60.0f; } else { if (_twistThetaRunningAverage > TWIST_DEADZONE) { - twistCorrection = glm::sign(_twistThetaRunningAverage) * pow((fabsf(_twistThetaRunningAverage) - TWIST_DEADZONE) / PI, POWER) * 80.0f; + twistCorrection = glm::sign(_twistThetaRunningAverage) * ((fabsf(_twistThetaRunningAverage) - TWIST_DEADZONE) / PI) * 60.0f; } } - if (fabsf(twistCorrection) > 45.0f) { - fred += glm::sign(twistCorrection) * 45.0f; + if (fabsf(twistCorrection) > 30.0f) { + fred += glm::sign(twistCorrection) * 30.0f; } else { fred += twistCorrection; } _lastTheta = 0.5f * _lastTheta + 0.5f * fred; + qCDebug(animation) << "twist correction: " << twistCorrection << " flex correction: " << flexCorrection << " ulnar correction " << ulnarCorrection; + //} /*else { @@ -435,14 +455,16 @@ const AnimPoseVec& AnimPoleVectorConstraint::evaluate(const AnimVariantMap& anim } */ - /* - if (fred < 70.0f) { - fred = 70.0f; + + if (fabsf(_lastTheta) < 50.0f) { + if (fabsf(_lastTheta) < 50.0f) { + _lastTheta = glm::sign(_lastTheta) * 50.0f; + } } - if (fred > 175.0f) { - fred = 175.0f; + if (fabsf(_lastTheta) > 175.0f) { + _lastTheta = glm::sign(_lastTheta) * 175.0f; } - */ + theta = ((180.0f - _lastTheta) / 180.0f)*PI; From fc978f0ee72b9c1c34995c5cb98004238feb5124 Mon Sep 17 00:00:00 2001 From: amantley Date: Wed, 13 Feb 2019 17:31:48 -0800 Subject: [PATCH 066/112] fixed twist angle bug. need to fix wrap around 180 to -180 behaviour --- libraries/animation/src/AnimPoleVectorConstraint.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/animation/src/AnimPoleVectorConstraint.cpp b/libraries/animation/src/AnimPoleVectorConstraint.cpp index bf246cf51a..22d45c5c85 100644 --- a/libraries/animation/src/AnimPoleVectorConstraint.cpp +++ b/libraries/animation/src/AnimPoleVectorConstraint.cpp @@ -311,8 +311,8 @@ const AnimPoseVec& AnimPoleVectorConstraint::evaluate(const AnimVariantMap& anim trueTwist.w *= -1.0f; } glm::vec3 trueTwistAxis = glm::axis(trueTwist); - float trueTwistTheta = glm::angle(trueTwist); - trueTwistTheta *= glm::sign(trueTwistAxis[1]) * glm::angle(trueTwist); + float trueTwistTheta; + trueTwistTheta = glm::sign(trueTwistAxis[1]) * glm::angle(trueTwist); _twistThetaRunningAverage = 0.5f * _twistThetaRunningAverage + 0.5f * trueTwistTheta; From aa0c52abd717c67008fc7a98e417aa066f726c4f Mon Sep 17 00:00:00 2001 From: Angus Antley Date: Wed, 13 Feb 2019 18:33:01 -0800 Subject: [PATCH 067/112] fixed wrap around 180 degrees --- .../animation/src/AnimPoleVectorConstraint.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/libraries/animation/src/AnimPoleVectorConstraint.cpp b/libraries/animation/src/AnimPoleVectorConstraint.cpp index 22d45c5c85..bfb63c052a 100644 --- a/libraries/animation/src/AnimPoleVectorConstraint.cpp +++ b/libraries/animation/src/AnimPoleVectorConstraint.cpp @@ -277,6 +277,10 @@ const AnimPoseVec& AnimPoleVectorConstraint::evaluate(const AnimVariantMap& anim glm::vec3 ulnarAxis = glm::axis(ulnarDeviation); //float twistTheta = glm::sign(twistAxis[1]) * glm::angle(twist); float ulnarDeviationTheta = glm::sign(ulnarAxis[2]) * glm::angle(ulnarDeviation); + if (glm::sign(ulnarDeviationTheta) != glm::sign(_ulnarRadialThetaRunningAverage) && fabsf(ulnarDeviationTheta) >(5.0f * PI) / 6.0f) { + // don't allow the theta to cross the 180 degree limit. + ulnarDeviationTheta = -1.0f * ulnarDeviationTheta; + } _ulnarRadialThetaRunningAverage = 0.5f * _ulnarRadialThetaRunningAverage + 0.5f * ulnarDeviationTheta; //get the swingTwist of the hand to lower arm @@ -297,6 +301,10 @@ const AnimPoseVec& AnimPoleVectorConstraint::evaluate(const AnimVariantMap& anim //float swingTheta = glm::angle(twistUlnarSwing); float flexTheta = glm::sign(flexAxis[0]) * glm::angle(flex); + if (glm::sign(flexTheta) != glm::sign(_flexThetaRunningAverage) && fabsf(flexTheta) > (5.0f * PI) / 6.0f) { + // don't allow the theta to cross the 180 degree limit. + flexTheta = -1.0f * flexTheta; + } _flexThetaRunningAverage = 0.5f * _flexThetaRunningAverage + 0.5f * flexTheta; @@ -313,6 +321,11 @@ const AnimPoseVec& AnimPoleVectorConstraint::evaluate(const AnimVariantMap& anim glm::vec3 trueTwistAxis = glm::axis(trueTwist); float trueTwistTheta; trueTwistTheta = glm::sign(trueTwistAxis[1]) * glm::angle(trueTwist); + if (glm::sign(trueTwistTheta) != glm::sign(_twistThetaRunningAverage) && fabsf(trueTwistTheta) >(5.0f * PI) / 6.0f) { + // don't allow the theta to cross the 180 degree limit. + trueTwistTheta = -1.0f * trueTwistTheta; + } + _twistThetaRunningAverage = 0.5f * _twistThetaRunningAverage + 0.5f * trueTwistTheta; From 1924018d2cb5ee24d5c1c6c3af353533097d51bb Mon Sep 17 00:00:00 2001 From: Angus Antley Date: Thu, 14 Feb 2019 07:15:58 -0800 Subject: [PATCH 068/112] added code to convert theta to a projected pole vector --- .../src/AnimPoleVectorConstraint.cpp | 69 +++++++------------ 1 file changed, 23 insertions(+), 46 deletions(-) diff --git a/libraries/animation/src/AnimPoleVectorConstraint.cpp b/libraries/animation/src/AnimPoleVectorConstraint.cpp index bfb63c052a..f230cfdad8 100644 --- a/libraries/animation/src/AnimPoleVectorConstraint.cpp +++ b/libraries/animation/src/AnimPoleVectorConstraint.cpp @@ -230,6 +230,19 @@ const AnimPoseVec& AnimPoleVectorConstraint::evaluate(const AnimVariantMap& anim glm::vec3 refVectorProj = refVector - glm::dot(refVector, unitAxis) * unitAxis; float refVectorProjLength = glm::length(refVectorProj); + float lastDot; + if ((_skeleton->nameToJointIndex("RightHand") == _tipJointIndex) || (_skeleton->nameToJointIndex("LeftHand") == _tipJointIndex)) { + //fake pole vector computation. + lastDot = cosf(((180.0f - _lastTheta) / 180.0f)*PI); + float lastSideDot = sqrt(1.0f - (lastDot*lastDot)); + glm::vec3 pretendPoleVector; + if (refVectorLength > MIN_LENGTH && sideVectorLength > MIN_LENGTH) { + poleVector = lastDot * (refVectorProj / refVectorProjLength) + glm::sign(_lastTheta) * lastSideDot * (sideVector / sideVectorLength); + } else { + poleVector = glm::vec3(1.0f, 0.0f, 0.0f); + } + } + // project poleVector on plane formed by axis. glm::vec3 poleVectorProj = poleVector - glm::dot(poleVector, unitAxis) * unitAxis; float poleVectorProjLength = glm::length(poleVectorProj); @@ -328,33 +341,13 @@ const AnimPoseVec& AnimPoleVectorConstraint::evaluate(const AnimVariantMap& anim _twistThetaRunningAverage = 0.5f * _twistThetaRunningAverage + 0.5f * trueTwistTheta; - - - - //while (trueTwistTheta > PI) { - // trueTwistTheta -= 2.0f * PI; - //} - - - // glm::vec3 eulerVersion = glm::eulerAngles(relativeHandRotation); if (!isLeft) { - qCDebug(animation) << "flex ave: " << (_flexThetaRunningAverage / PI) * 180.0f << " twist ave: " << (_twistThetaRunningAverage / PI) * 180.0f << " ulnar deviation ave: " << (_ulnarRadialThetaRunningAverage / PI) * 180.0f; - qCDebug(animation) << "flex: " << (flexTheta / PI) * 180.0f << " twist: " << (trueTwistTheta / PI) * 180.0f << " ulnar deviation: " << (ulnarDeviationTheta / PI) * 180.0f; - //qCDebug(animation) << "trueTwist: " << (trueTwistTheta / PI) * 180.0f;// << " old twist: " << (twistTheta / PI) * 180.0f; - //qCDebug(animation) << "ulnarAxis " << flexUlnarAxis; - // qCDebug(animation) << "relative hand rotation " << relativeHandRotation; - // qCDebug(animation) << "twist rotation " << trueTwist; - - //QString name = QString("handMarker3"); - //const vec4 WHITE(1.0f); - //DebugDraw::getInstance().addMyAvatarMarker(name, relativeHandRotation, midPose.trans(), WHITE); + //qCDebug(animation) << "flex ave: " << (_flexThetaRunningAverage / PI) * 180.0f << " twist ave: " << (_twistThetaRunningAverage / PI) * 180.0f << " ulnar deviation ave: " << (_ulnarRadialThetaRunningAverage / PI) * 180.0f; + //qCDebug(animation) << "flex: " << (flexTheta / PI) * 180.0f << " twist: " << (trueTwistTheta / PI) * 180.0f << " ulnar deviation: " << (ulnarDeviationTheta / PI) * 180.0f; + } - //QString name = QString("wrist_target").arg(_id); - //glm::vec4 markerColor(1.0f, 1.0f, 0.0f, 0.0f); - //DebugDraw::getInstance().addMyAvatarMarker(name, midPose.rot(), midPose.trans(), markerColor); - // here is where we would do the wrist correction. float deltaTheta = correctElbowForHandFlexionExtension(tipPose, midPose); float deltaThetaUlnar; @@ -374,9 +367,9 @@ const AnimPoseVec& AnimPoleVectorConstraint::evaluate(const AnimVariantMap& anim float flexCorrection = 0.0f; if (isLeft) { if (_flexThetaRunningAverage > FLEX_BOUNDARY) { - flexCorrection = ((_flexThetaRunningAverage - FLEX_BOUNDARY) / PI) * 90.0f; // glm::sign(flexTheta) * pow((flexTheta - FLEX_BOUNDARY) / PI, POWER) * 180.0f; + flexCorrection = ((_flexThetaRunningAverage - FLEX_BOUNDARY) / PI) * 180.0f; } else if (_flexThetaRunningAverage < EXTEND_BOUNDARY) { - flexCorrection = ((_flexThetaRunningAverage - EXTEND_BOUNDARY) / PI) * 90.0f; // glm::sign(flexTheta) * pow((flexTheta - EXTEND_BOUNDARY) / PI, POWER) * 180.0f; + flexCorrection = ((_flexThetaRunningAverage - EXTEND_BOUNDARY) / PI) * 180.0f; } if (fabs(flexCorrection) > 30.0f) { flexCorrection = glm::sign(flexCorrection) * 30.0f; @@ -384,9 +377,9 @@ const AnimPoseVec& AnimPoleVectorConstraint::evaluate(const AnimVariantMap& anim fred += flexCorrection; } else { if (_flexThetaRunningAverage > FLEX_BOUNDARY) { - flexCorrection = ((_flexThetaRunningAverage - FLEX_BOUNDARY) / PI) * 180.0f; // glm::sign(flexTheta) * pow((flexTheta - FLEX_BOUNDARY) / PI, POWER) * 180.0f; + flexCorrection = ((_flexThetaRunningAverage - FLEX_BOUNDARY) / PI) * 180.0f; } else if (_flexThetaRunningAverage < EXTEND_BOUNDARY) { - flexCorrection = ((_flexThetaRunningAverage - EXTEND_BOUNDARY) / PI) * 180.0f; // glm::sign(flexTheta) * pow((flexTheta - EXTEND_BOUNDARY) / PI, POWER) * 180.0f; + flexCorrection = ((_flexThetaRunningAverage - EXTEND_BOUNDARY) / PI) * 180.0f; } if (fabs(flexCorrection) > 30.0f) { flexCorrection = glm::sign(flexCorrection) * 30.0f; @@ -452,22 +445,7 @@ const AnimPoseVec& AnimPoleVectorConstraint::evaluate(const AnimVariantMap& anim _lastTheta = 0.5f * _lastTheta + 0.5f * fred; - qCDebug(animation) << "twist correction: " << twistCorrection << " flex correction: " << flexCorrection << " ulnar correction " << ulnarCorrection; - - //} - - /*else { - if (trueTwistTheta < -TWIST_DEADZONE) { - fred -= glm::sign(trueTwistTheta) * pow((fabsf(trueTwistTheta) - TWIST_DEADZONE) / PI, POWER) * 90.0f; - } else { - if (trueTwistTheta > TWIST_DEADZONE) { - fred -= glm::sign(trueTwistTheta) * pow((fabsf(trueTwistTheta) - TWIST_DEADZONE) / PI, POWER) * 90.0f; - } - } - - - } - */ + //qCDebug(animation) << "twist correction: " << twistCorrection << " flex correction: " << flexCorrection << " ulnar correction " << ulnarCorrection; if (fabsf(_lastTheta) < 50.0f) { if (fabsf(_lastTheta) < 50.0f) { @@ -478,10 +456,9 @@ const AnimPoseVec& AnimPoleVectorConstraint::evaluate(const AnimVariantMap& anim _lastTheta = glm::sign(_lastTheta) * 175.0f; } - + float poleVectorTheta = theta; theta = ((180.0f - _lastTheta) / 180.0f)*PI; - - //qCDebug(animation) << "the wrist correction theta is -----> " << isLeft << " theta: " << deltaTheta; + qCDebug(animation) << "fake theta " << poleVectorTheta << " newly computed theta " << theta << " dot " << dot << " last dot "<< lastDot; } From 3e66bce11262807205f8f2506233707c6abd61ef Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Thu, 14 Feb 2019 18:30:37 -0700 Subject: [PATCH 069/112] set useFlow function --- interface/src/avatar/MyAvatar.cpp | 55 ++++++++++ interface/src/avatar/MyAvatar.h | 10 ++ libraries/animation/src/Flow.cpp | 102 ++++++++++++++---- libraries/animation/src/Flow.h | 20 ++-- libraries/animation/src/Rig.cpp | 4 +- .../src/avatars-renderer/Avatar.cpp | 1 - 6 files changed, 161 insertions(+), 31 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index d5f8f8a3ec..ce751add0b 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -5320,3 +5320,58 @@ void MyAvatar::addAvatarHandsToFlow(const std::shared_ptr& otherAvatar) flow.setOthersCollision(otherAvatar->getID(), jointIndex, position); } } + +void MyAvatar::useFlow(const QVariantMap& physicsConfig, const QVariantMap& collisionsConfig) { + if (_skeletonModel->isLoaded()) { + auto &flow = _skeletonModel->getRig().getFlow(); + flow.init(); + auto physicsGroups = physicsConfig.keys(); + if (physicsGroups.size() > 0) { + for (auto &groupName : physicsGroups) { + auto &settings = physicsConfig[groupName].toMap(); + FlowPhysicsSettings physicsSettings = flow.getPhysicsSettingsForGroup(groupName); + if (settings.contains("active")) { + physicsSettings._active = settings["active"].toBool(); + } + if (settings.contains("damping")) { + physicsSettings._damping = settings["damping"].toFloat(); + } + if (settings.contains("delta")) { + physicsSettings._delta = settings["delta"].toFloat(); + } + if (settings.contains("gravity")) { + physicsSettings._gravity = settings["gravity"].toFloat(); + } + if (settings.contains("inertia")) { + physicsSettings._inertia = settings["inertia"].toFloat(); + } + if (settings.contains("radius")) { + physicsSettings._radius = settings["radius"].toFloat(); + } + if (settings.contains("stiffness")) { + physicsSettings._stiffness = settings["stiffness"].toFloat(); + } + flow.setPhysicsSettingsForGroup(groupName, physicsSettings); + } + } + auto collisionJoints = collisionsConfig.keys(); + if (collisionJoints.size() > 0) { + auto &collisionSystem = flow.getCollisionSystem(); + collisionSystem.resetCollisions(); + for (auto &jointName : collisionJoints) { + int jointIndex = getJointIndex(jointName); + FlowCollisionSettings collisionsSettings; + auto &settings = collisionsConfig[jointName].toMap(); + collisionsSettings._entityID = getID(); + if (settings.contains("radius")) { + collisionsSettings._radius = settings["radius"].toFloat(); + } + if (settings.contains("offset")) { + collisionsSettings._offset = vec3FromVariant(settings["offset"]); + } + collisionSystem.addCollisionSphere(jointIndex, collisionsSettings); + } + + } + } +} \ No newline at end of file diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 996abcabf2..f753da4fa0 100755 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -1185,6 +1185,16 @@ public: void addAvatarHandsToFlow(const std::shared_ptr& otherAvatar); + /**jsdoc + * Init flow simulation on avatar. + * @function MyAvatar.useFlow + * @param {Object} physicsConfig - object with the customized physic parameters + * i.e. {"hair": {"active": true, "stiffness": 0.0, "radius": 0.04, "gravity": -0.035, "damping": 0.8, "inertia": 0.8, "delta": 0.35}} + * @param {Object} collisionsConfig - object with the customized collision parameters + * i.e. {"Spine2": {"type": "sphere", "radius": 0.14, "offset": {"x": 0.0, "y": 0.2, "z": 0.0}}} + */ + Q_INVOKABLE void useFlow(const QVariantMap& flowConfig = QVariantMap(), const QVariantMap& collisionsConfig = QVariantMap()); + public slots: /**jsdoc diff --git a/libraries/animation/src/Flow.cpp b/libraries/animation/src/Flow.cpp index ab22e25326..3db0068434 100644 --- a/libraries/animation/src/Flow.cpp +++ b/libraries/animation/src/Flow.cpp @@ -176,7 +176,7 @@ void FlowCollisionSystem::modifySelfCollisionRadius(int jointIndex, float radius int collisionIndex = findSelfCollisionWithJoint(jointIndex); if (collisionIndex > -1) { _selfCollisions[collisionIndex]._initialRadius = radius; - _selfCollisions[collisionIndex]._radius = _scale * radius; + //_selfCollisions[collisionIndex]._radius = _scale * radius; } }; @@ -185,7 +185,7 @@ void FlowCollisionSystem::modifySelfCollisionYOffset(int jointIndex, float offse if (collisionIndex > -1) { auto currentOffset = _selfCollisions[collisionIndex]._offset; _selfCollisions[collisionIndex]._initialOffset = glm::vec3(currentOffset.x, offset, currentOffset.z); - _selfCollisions[collisionIndex]._offset = _selfCollisions[collisionIndex]._initialOffset * _scale; + //_selfCollisions[collisionIndex]._offset = _selfCollisions[collisionIndex]._initialOffset * _scale; } }; @@ -193,11 +193,27 @@ void FlowCollisionSystem::modifySelfCollisionOffset(int jointIndex, const glm::v int collisionIndex = findSelfCollisionWithJoint(jointIndex); if (collisionIndex > -1) { _selfCollisions[collisionIndex]._initialOffset = offset; - _selfCollisions[collisionIndex]._offset = _selfCollisions[collisionIndex]._initialOffset * _scale; + //_selfCollisions[collisionIndex]._offset = _selfCollisions[collisionIndex]._initialOffset * _scale; } }; - - +FlowCollisionSettings FlowCollisionSystem::getCollisionSettingsByJoint(int jointIndex) { + for (auto &collision : _selfCollisions) { + if (collision._jointIndex == jointIndex) { + return FlowCollisionSettings(collision._entityID, FlowCollisionType::CollisionSphere, collision._initialOffset, collision._initialRadius); + } + } + return FlowCollisionSettings(); +} +void FlowCollisionSystem::setCollisionSettingsByJoint(int jointIndex, const FlowCollisionSettings& settings) { + for (auto &collision : _selfCollisions) { + if (collision._jointIndex == jointIndex) { + collision._initialRadius = settings._radius; + collision._initialOffset = settings._offset; + collision._radius = _scale * settings._radius; + collision._offset = _scale * settings._offset; + } + } +} void FlowCollisionSystem::prepareCollisions() { _allCollisions.clear(); _allCollisions.resize(_selfCollisions.size() + _othersCollisions.size()); @@ -206,6 +222,11 @@ void FlowCollisionSystem::prepareCollisions() { _othersCollisions.clear(); } +FlowNode::FlowNode(const glm::vec3& initialPosition, FlowPhysicsSettings settings) { + _initialPosition = _previousPosition = _currentPosition = initialPosition; + _initialRadius = settings._radius; +} + void FlowNode::update(float deltaTime, const glm::vec3& accelerationOffset) { _acceleration = glm::vec3(0.0f, _settings._gravity, 0.0f); _previousVelocity = _currentVelocity; @@ -215,15 +236,16 @@ void FlowNode::update(float deltaTime, const glm::vec3& accelerationOffset) { // Add inertia const float FPS = 60.0f; float timeRatio = (FPS * deltaTime); - + float invertedTimeRatio = timeRatio > 0.0f ? 1.0f / timeRatio : 1.0f; auto deltaVelocity = _previousVelocity - _currentVelocity; auto centrifugeVector = glm::length(deltaVelocity) != 0.0f ? glm::normalize(deltaVelocity) : glm::vec3(); - _acceleration = _acceleration + centrifugeVector * _settings._inertia * glm::length(_currentVelocity) * (1 / timeRatio); + _acceleration = _acceleration + centrifugeVector * _settings._inertia * glm::length(_currentVelocity) * invertedTimeRatio; // Add offset _acceleration += accelerationOffset; - glm::vec3 deltaAcceleration = timeRatio * _acceleration * glm::pow(_settings._delta * _scale, 2); + //glm::vec3 deltaAcceleration = timeRatio * _acceleration * glm::pow(_settings._delta * _scale, 2); + glm::vec3 deltaAcceleration = timeRatio * _acceleration * glm::pow(_settings._delta, 2); // Calculate new position _currentPosition = (_currentPosition + _currentVelocity * _settings._damping) + deltaAcceleration; } @@ -257,11 +279,10 @@ void FlowNode::solveCollisions(const FlowCollisionResult& collision) { } }; -FlowJoint::FlowJoint(int jointIndex, int parentIndex, int childIndex, const QString& name, const QString& group, float scale, const FlowPhysicsSettings& settings) { +FlowJoint::FlowJoint(int jointIndex, int parentIndex, int childIndex, const QString& name, const QString& group, const FlowPhysicsSettings& settings) { _index = jointIndex; _name = name; _group = group; - _scale = scale; _childIndex = childIndex; _parentIndex = parentIndex; _node = FlowNode(glm::vec3(), settings); @@ -276,8 +297,7 @@ void FlowJoint::setInitialData(const glm::vec3& initialPosition, const glm::vec3 _initialRotation = initialRotation; _translationDirection = glm::normalize(_initialTranslation); _parentPosition = parentPosition; - _length = glm::length(_initialPosition - parentPosition); - _originalLength = _length / _scale; + _initialLength = _length = glm::length(_initialPosition - parentPosition); } void FlowJoint::setUpdatedData(const glm::vec3& updatedPosition, const glm::vec3& updatedTranslation, const glm::quat& updatedRotation, const glm::vec3& parentPosition, const glm::quat& parentWorldRotation) { @@ -313,8 +333,8 @@ void FlowJoint::solve(const FlowCollisionResult& collision) { _node.solve(_parentPosition, _length, collision); }; -FlowDummyJoint::FlowDummyJoint(const glm::vec3& initialPosition, int index, int parentIndex, int childIndex, float scale, FlowPhysicsSettings settings) : - FlowJoint(index, parentIndex, childIndex, DUMMY_KEYWORD + "_" + index, DUMMY_KEYWORD, scale, settings) { +FlowDummyJoint::FlowDummyJoint(const glm::vec3& initialPosition, int index, int parentIndex, int childIndex, FlowPhysicsSettings settings) : + FlowJoint(index, parentIndex, childIndex, DUMMY_KEYWORD + "_" + index, DUMMY_KEYWORD, settings) { _isDummy = true; _initialPosition = initialPosition; _node = FlowNode(_initialPosition, settings); @@ -451,6 +471,12 @@ bool FlowThread::getActive() { return _jointsPointer->at(_joints[0])._node._active; }; +void Flow::init() { + if (!_initialized) { + calculateConstraints(); + } +} + void Flow::calculateConstraints() { cleanUp(); if (!_rig) { @@ -507,7 +533,7 @@ void Flow::calculateConstraints() { jointSettings = DEFAULT_JOINT_SETTINGS; } if (_flowJointData.find(i) == _flowJointData.end()) { - auto flowJoint = FlowJoint(i, parentIndex, -1, name, group, _scale, jointSettings); + auto flowJoint = FlowJoint(i, parentIndex, -1, name, group, jointSettings); _flowJointData.insert(std::pair(i, flowJoint)); } } @@ -553,7 +579,7 @@ void Flow::calculateConstraints() { auto newSettings = FlowPhysicsSettings(joint._node._settings); newSettings._stiffness = ISOLATED_JOINT_STIFFNESS; int extraIndex = (int)_flowJointData.size(); - auto newJoint = FlowDummyJoint(jointPosition, extraIndex, jointIndex, -1, _scale, newSettings); + auto newJoint = FlowDummyJoint(jointPosition, extraIndex, jointIndex, -1, newSettings); newJoint._isDummy = false; newJoint._length = ISOLATED_JOINT_LENGTH; newJoint._childIndex = extraIndex; @@ -575,7 +601,7 @@ void Flow::calculateConstraints() { int parentIndex = rightHandIndex; for (int i = 0; i < DUMMY_JOINT_COUNT; i++) { int childIndex = (i == (DUMMY_JOINT_COUNT - 1)) ? -1 : extraIndex + 1; - auto newJoint = FlowDummyJoint(rightHandPosition, extraIndex, parentIndex, childIndex, _scale, DEFAULT_JOINT_SETTINGS); + auto newJoint = FlowDummyJoint(rightHandPosition, extraIndex, parentIndex, childIndex, DEFAULT_JOINT_SETTINGS); _flowJointData.insert(std::pair(extraIndex, newJoint)); parentIndex = extraIndex; extraIndex++; @@ -601,24 +627,39 @@ void Flow::cleanUp() { _flowJointKeywords.clear(); _collisionSystem.resetCollisions(); _initialized = false; + _isScaleSet = false; _active = false; } void Flow::setTransform(float scale, const glm::vec3& position, const glm::quat& rotation) { _scale = scale; - for (auto &joint : _flowJointData) { - joint.second._scale = scale; - joint.second._node._scale = scale; - } _entityPosition = position; _entityRotation = rotation; - _active = true; + _active = _initialized; } void Flow::update(float deltaTime) { if (_initialized && _active) { QElapsedTimer _timer; _timer.start(); + if (_scale != _lastScale) { + if (!_isScaleSet) { + for (auto &joint: _flowJointData) { + joint.second._initialLength = joint.second._length / _scale; + } + _isScaleSet = true; + } + _lastScale = _scale; + _collisionSystem.setScale(_scale); + for (int i = 0; i < _jointThreads.size(); i++) { + for (int j = 0; j < _jointThreads[i]._joints.size(); j++) { + auto &joint = _flowJointData[_jointThreads[i]._joints[j]]; + joint._node._settings._radius = joint._node._initialRadius * _scale; + joint._length = joint._initialLength * _scale; + } + _jointThreads[i].resetLength(); + } + } updateJoints(); for (size_t i = 0; i < _jointThreads.size(); i++) { size_t index = _invertThreadLoop ? _jointThreads.size() - 1 - i : i; @@ -710,4 +751,21 @@ void Flow::setOthersCollision(const QUuid& otherId, int jointIndex, const glm::v settings._entityID = otherId; settings._radius = HAND_COLLISION_RADIUS; _collisionSystem.addCollisionSphere(jointIndex, settings, position, false, true); +} + +FlowPhysicsSettings Flow::getPhysicsSettingsForGroup(const QString& group) { + for (auto &joint : _flowJointData) { + if (joint.second._group.toUpper() == group.toUpper()) { + return joint.second._node._settings; + } + } + return FlowPhysicsSettings(); +} + +void Flow::setPhysicsSettingsForGroup(const QString& group, const FlowPhysicsSettings& settings) { + for (auto &joint : _flowJointData) { + if (joint.second._group.toUpper() == group.toUpper()) { + joint.second._node._settings = settings; + } + } } \ No newline at end of file diff --git a/libraries/animation/src/Flow.h b/libraries/animation/src/Flow.h index a06f785da2..7f77df0beb 100644 --- a/libraries/animation/src/Flow.h +++ b/libraries/animation/src/Flow.h @@ -155,7 +155,6 @@ public: FlowCollisionSystem() {}; void addCollisionSphere(int jointIndex, const FlowCollisionSettings& settings, const glm::vec3& position = { 0.0f, 0.0f, 0.0f }, bool isSelfCollision = true, bool isTouch = false); FlowCollisionResult computeCollision(const std::vector collisions); - void setScale(float scale); std::vector checkFlowThreadCollisions(FlowThread* flowThread); @@ -169,6 +168,9 @@ public: void prepareCollisions(); void resetCollisions(); void resetOthersCollisions() { _othersCollisions.clear(); } + void setScale(float scale); + FlowCollisionSettings getCollisionSettingsByJoint(int jointIndex); + void setCollisionSettingsByJoint(int jointIndex, const FlowCollisionSettings& settings); protected: std::vector _selfCollisions; std::vector _othersCollisions; @@ -179,8 +181,7 @@ protected: class FlowNode { public: FlowNode() {}; - FlowNode(const glm::vec3& initialPosition, FlowPhysicsSettings settings) : - _initialPosition(initialPosition), _previousPosition(initialPosition), _currentPosition(initialPosition){}; + FlowNode(const glm::vec3& initialPosition, FlowPhysicsSettings settings); FlowPhysicsSettings _settings; glm::vec3 _initialPosition; @@ -195,7 +196,6 @@ public: FlowCollisionResult _previousCollision; float _initialRadius { 0.0f }; - float _scale{ 1.0f }; bool _anchored { false }; bool _colliding { false }; @@ -210,7 +210,7 @@ public: class FlowJoint { public: FlowJoint() {}; - FlowJoint(int jointIndex, int parentIndex, int childIndex, const QString& name, const QString& group, float scale, const FlowPhysicsSettings& settings); + FlowJoint(int jointIndex, int parentIndex, int childIndex, const QString& name, const QString& group, const FlowPhysicsSettings& settings); void setInitialData(const glm::vec3& initialPosition, const glm::vec3& initialTranslation, const glm::quat& initialRotation, const glm::vec3& parentPosition); void setUpdatedData(const glm::vec3& updatedPosition, const glm::vec3& updatedTranslation, const glm::quat& updatedRotation, const glm::vec3& parentPosition, const glm::quat& parentWorldRotation); void setRecoveryPosition(const glm::vec3& recoveryPosition); @@ -241,13 +241,13 @@ public: glm::vec3 _translationDirection; float _scale { 1.0f }; float _length { 0.0f }; - float _originalLength { 0.0f }; + float _initialLength { 0.0f }; bool _applyRecovery { false }; }; class FlowDummyJoint : public FlowJoint { public: - FlowDummyJoint(const glm::vec3& initialPosition, int index, int parentIndex, int childIndex, float scale, FlowPhysicsSettings settings); + FlowDummyJoint(const glm::vec3& initialPosition, int index, int parentIndex, int childIndex, FlowPhysicsSettings settings); }; @@ -277,6 +277,8 @@ public: class Flow { public: Flow(Rig* rig) { _rig = rig; }; + void init(); + bool isActive() { return _active; } void calculateConstraints(); void update(float deltaTime); void setTransform(float scale, const glm::vec3& position, const glm::quat& rotation); @@ -284,6 +286,8 @@ public: const std::vector& getThreads() const { return _jointThreads; } void setOthersCollision(const QUuid& otherId, int jointIndex, const glm::vec3& position); FlowCollisionSystem& getCollisionSystem() { return _collisionSystem; } + FlowPhysicsSettings getPhysicsSettingsForGroup(const QString& group); + void setPhysicsSettingsForGroup(const QString& group, const FlowPhysicsSettings& settings); private: void setJoints(); void cleanUp(); @@ -292,6 +296,7 @@ private: bool worldToJointPoint(const glm::vec3& position, const int jointIndex, glm::vec3& jointSpacePosition) const; Rig* _rig; float _scale { 1.0f }; + float _lastScale{ 1.0f }; glm::vec3 _entityPosition; glm::quat _entityRotation; std::map _flowJointData; @@ -300,6 +305,7 @@ private: FlowCollisionSystem _collisionSystem; bool _initialized { false }; bool _active { false }; + bool _isScaleSet { false }; int _deltaTime { 0 }; int _deltaTimeLimit { 4000000 }; int _updates { 0 }; diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index e6e4f74c11..9b6d97d919 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -1905,7 +1905,9 @@ void Rig::initAnimGraph(const QUrl& url) { qCritical(animation) << "Error loading: code = " << error << "str =" << str; }); connect(this, &Rig::onLoadComplete, [&]() { - _flow.calculateConstraints(); + if (_flow.isActive()) { + _flow.calculateConstraints(); + } }); } } diff --git a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp index 223813eecb..50cb813c3a 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp +++ b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp @@ -736,7 +736,6 @@ void Avatar::postUpdate(float deltaTime, const render::ScenePointer& scene) { // glm::vec3 pos2 = joints.find(joint.second._parentIndex) != joints.end() ? joints[joint.second._parentIndex]._node._currentPosition : getJointPosition(joint.second._parentIndex); // DebugDraw::getInstance().drawRay(pos1, pos2, glm::vec4(1.0f, 1.0f, 1.0f, 1.0f)); DebugDraw::getInstance().drawRay(joints[index1]._node._currentPosition, joints[index2]._node._currentPosition, glm::vec4(1.0f, 1.0f, 1.0f, 1.0f)); - } } } From 88eae0f2ec7586fae9d286d5af9cacaf9b3634b7 Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Thu, 14 Feb 2019 18:49:49 -0700 Subject: [PATCH 070/112] Remove test functions --- interface/src/avatar/AvatarManager.cpp | 103 ------------------ interface/src/avatar/AvatarManager.h | 9 -- .../src/avatars-renderer/Avatar.h | 3 - libraries/entities/src/EntityTree.cpp | 6 - libraries/entities/src/EntityTree.h | 1 - 5 files changed, 122 deletions(-) diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index d2ba7149f2..685619aed8 100755 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -763,109 +763,6 @@ RayToAvatarIntersectionResult AvatarManager::findRayIntersectionVector(const Pic return result; } -RayToAvatarIntersectionResult AvatarManager::findRayIntersectionOld(const PickRay& ray, - const QScriptValue& avatarIdsToInclude, - const QScriptValue& avatarIdsToDiscard) { - QVector avatarsToInclude = qVectorEntityItemIDFromScriptValue(avatarIdsToInclude); - QVector avatarsToDiscard = qVectorEntityItemIDFromScriptValue(avatarIdsToDiscard); - - return findRayIntersectionVectorOld(ray, avatarsToInclude, avatarsToDiscard); -} - -RayToAvatarIntersectionResult AvatarManager::findRayIntersectionVectorOld(const PickRay& ray, - const QVector& avatarsToInclude, - const QVector& avatarsToDiscard) { - RayToAvatarIntersectionResult result; - if (QThread::currentThread() != thread()) { - BLOCKING_INVOKE_METHOD(const_cast(this), "findRayIntersectionVector", - Q_RETURN_ARG(RayToAvatarIntersectionResult, result), - Q_ARG(const PickRay&, ray), - Q_ARG(const QVector&, avatarsToInclude), - Q_ARG(const QVector&, avatarsToDiscard)); - return result; - } - - // It's better to intersect the ray against the avatar's actual mesh, but this is currently difficult to - // do, because the transformed mesh data only exists over in GPU-land. As a compromise, this code - // intersects against the avatars capsule and then against the (T-pose) mesh. The end effect is that picking - // against the avatar is sort-of right, but you likely wont be able to pick against the arms. - - // TODO -- find a way to extract transformed avatar mesh data from the rendering engine. - - std::vector sortedAvatars; - auto avatarHashCopy = getHashCopy(); - for (auto avatarData : avatarHashCopy) { - auto avatar = std::static_pointer_cast(avatarData); - if ((avatarsToInclude.size() > 0 && !avatarsToInclude.contains(avatar->getID())) || - (avatarsToDiscard.size() > 0 && avatarsToDiscard.contains(avatar->getID()))) { - continue; - } - - float distance = FLT_MAX; -#if 0 - // if we weren't picking against the capsule, we would want to pick against the avatarBounds... - SkeletonModelPointer avatarModel = avatar->getSkeletonModel(); - AABox avatarBounds = avatarModel->getRenderableMeshBound(); - if (avatarBounds.contains(ray.origin)) { - distance = 0.0f; - } - else { - float boundDistance = FLT_MAX; - BoxFace face; - glm::vec3 surfaceNormal; - if (avatarBounds.findRayIntersection(ray.origin, ray.direction, boundDistance, face, surfaceNormal)) { - distance = boundDistance; - } - } -#else - glm::vec3 start; - glm::vec3 end; - float radius; - avatar->getCapsule(start, end, radius); - findRayCapsuleIntersection(ray.origin, ray.direction, start, end, radius, distance); -#endif - - if (distance < FLT_MAX) { - sortedAvatars.emplace_back(distance, avatar); - } - } - - if (sortedAvatars.size() > 1) { - static auto comparator = [](const SortedAvatar& left, const SortedAvatar& right) { return left.first < right.first; }; - std::sort(sortedAvatars.begin(), sortedAvatars.end(), comparator); - } - - for (auto it = sortedAvatars.begin(); it != sortedAvatars.end(); ++it) { - const SortedAvatar& sortedAvatar = *it; - // We can exit once avatarCapsuleDistance > bestDistance - if (sortedAvatar.first > result.distance) { - break; - } - - float distance = FLT_MAX; - BoxFace face; - glm::vec3 surfaceNormal; - QVariantMap extraInfo; - SkeletonModelPointer avatarModel = sortedAvatar.second->getSkeletonModel(); - if (avatarModel->findRayIntersectionAgainstSubMeshes(ray.origin, ray.direction, distance, face, surfaceNormal, extraInfo, true)) { - if (distance < result.distance) { - result.intersects = true; - result.avatarID = sortedAvatar.second->getID(); - result.distance = distance; - result.face = face; - result.surfaceNormal = surfaceNormal; - result.extraInfo = extraInfo; - } - } - } - - if (result.intersects) { - result.intersection = ray.origin + ray.direction * result.distance; - } - - return result; -} - ParabolaToAvatarIntersectionResult AvatarManager::findParabolaIntersectionVector(const PickParabola& pick, const QVector& avatarsToInclude, const QVector& avatarsToDiscard) { diff --git a/interface/src/avatar/AvatarManager.h b/interface/src/avatar/AvatarManager.h index 66f28206e0..50d9e80e8b 100644 --- a/interface/src/avatar/AvatarManager.h +++ b/interface/src/avatar/AvatarManager.h @@ -157,15 +157,6 @@ public: const QVector& avatarsToDiscard, bool pickAgainstMesh); - Q_INVOKABLE RayToAvatarIntersectionResult findRayIntersectionOld(const PickRay& ray, - const QScriptValue& avatarIdsToInclude = QScriptValue(), - const QScriptValue& avatarIdsToDiscard = QScriptValue()); - - Q_INVOKABLE RayToAvatarIntersectionResult findRayIntersectionVectorOld(const PickRay& ray, - const QVector& avatarsToInclude, - const QVector& avatarsToDiscard); - - /**jsdoc * @function AvatarManager.findParabolaIntersectionVector * @param {PickParabola} pick diff --git a/libraries/avatars-renderer/src/avatars-renderer/Avatar.h b/libraries/avatars-renderer/src/avatars-renderer/Avatar.h index 4ba2ffc07d..b43fe012b7 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/Avatar.h +++ b/libraries/avatars-renderer/src/avatars-renderer/Avatar.h @@ -35,7 +35,6 @@ #include "MetaModelPayload.h" #include "MultiSphereShape.h" -#include "Flow.h" namespace render { template <> const ItemKey payloadGetKey(const AvatarSharedPointer& avatar); @@ -286,8 +285,6 @@ public: */ Q_INVOKABLE glm::quat jointToWorldRotation(const glm::quat& rotation, const int jointIndex = -1) const; - Q_INVOKABLE void callFlow() { _skeletonModel->getRig().computeFlowSkeleton(); }; - virtual void setSkeletonModelURL(const QUrl& skeletonModelURL) override; virtual void setAttachmentData(const QVector& attachmentData) override; diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index 47064bdbd3..954462a9f2 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -2943,12 +2943,6 @@ int EntityTree::getJointIndex(const QUuid& entityID, const QString& name) const } return entity->getJointIndex(name); } -void EntityTree::callFlowSkeleton(const QUuid& entityID) { - /* - EntityTree* nonConstThis = const_cast(this); - EntityItemPointer entity = nonConstThis->findEntityByEntityItemID(entityID); - */ -} QStringList EntityTree::getJointNames(const QUuid& entityID) const { EntityTree* nonConstThis = const_cast(this); diff --git a/libraries/entities/src/EntityTree.h b/libraries/entities/src/EntityTree.h index cc80083e0d..f9b7b8d67f 100644 --- a/libraries/entities/src/EntityTree.h +++ b/libraries/entities/src/EntityTree.h @@ -240,7 +240,6 @@ public: // these are used to call through to EntityItems Q_INVOKABLE int getJointIndex(const QUuid& entityID, const QString& name) const; Q_INVOKABLE QStringList getJointNames(const QUuid& entityID) const; - Q_INVOKABLE void callFlowSkeleton(const QUuid& entityID); void knowAvatarID(QUuid avatarID) { _avatarIDs += avatarID; } void forgetAvatarID(QUuid avatarID) { _avatarIDs -= avatarID; } From 5c26bbec5ca90e651fad42476ae6fc8a3737ad5d Mon Sep 17 00:00:00 2001 From: amantley Date: Thu, 14 Feb 2019 18:06:20 -0800 Subject: [PATCH 071/112] moving the theta calculation to rig --- .../src/AnimPoleVectorConstraint.cpp | 36 +- libraries/animation/src/Rig.cpp | 373 +++++++++++++++++- libraries/animation/src/Rig.h | 9 + 3 files changed, 410 insertions(+), 8 deletions(-) diff --git a/libraries/animation/src/AnimPoleVectorConstraint.cpp b/libraries/animation/src/AnimPoleVectorConstraint.cpp index f230cfdad8..fa78793dd2 100644 --- a/libraries/animation/src/AnimPoleVectorConstraint.cpp +++ b/libraries/animation/src/AnimPoleVectorConstraint.cpp @@ -177,8 +177,16 @@ const AnimPoseVec& AnimPoleVectorConstraint::evaluate(const AnimVariantMap& anim _poses = underPoses; } + + + // Look up poleVector from animVars, make sure to convert into geom space. glm::vec3 poleVector = animVars.lookupRigToGeometryVector(_poleVectorVar, Vectors::UNIT_Z); + if (_skeleton->nameToJointIndex("LeftHand") == _tipJointIndex) { + + float thetaFromRig = animVars.lookup("thetaRight", 0.0f); + qCDebug(animation) << " anim pole vector theta from rig " << thetaFromRig; + } // determine if we should interpolate bool enabled = animVars.lookup(_enabledVar, _enabled); @@ -238,11 +246,14 @@ const AnimPoseVec& AnimPoleVectorConstraint::evaluate(const AnimVariantMap& anim glm::vec3 pretendPoleVector; if (refVectorLength > MIN_LENGTH && sideVectorLength > MIN_LENGTH) { poleVector = lastDot * (refVectorProj / refVectorProjLength) + glm::sign(_lastTheta) * lastSideDot * (sideVector / sideVectorLength); + if (_skeleton->nameToJointIndex("LeftHand") == _tipJointIndex) { + qCDebug(animation) << " anim pole vector computed: " << poleVector; + } } else { poleVector = glm::vec3(1.0f, 0.0f, 0.0f); } } - + // project poleVector on plane formed by axis. glm::vec3 poleVectorProj = poleVector - glm::dot(poleVector, unitAxis) * unitAxis; float poleVectorProjLength = glm::length(poleVectorProj); @@ -262,7 +273,18 @@ const AnimPoseVec& AnimPoleVectorConstraint::evaluate(const AnimVariantMap& anim if (_skeleton->nameToJointIndex("LeftHand") == _tipJointIndex) { isLeft = true; } - fred = findThetaNewWay(tipPose.trans(), basePose.trans(), isLeft); + //qCDebug(animation) << "hand pose anim pole vector: " << isLeft << " isLeft " << tipPose; + //fred = findThetaNewWay(tipPose.trans(), basePose.trans(), isLeft); + if (isLeft) { + float thetaFromRig = animVars.lookup("thetaLeft", 0.0f); + qCDebug(animation) << " anim pole vector theta from rig left" << thetaFromRig; + fred = thetaFromRig; + + } else { + float thetaFromRig = animVars.lookup("thetaRight", 0.0f); + qCDebug(animation) << " anim pole vector theta from rig right" << thetaFromRig; + fred = thetaFromRig; + } glm::quat relativeHandRotation = (midPose.inverse() * tipPose).rot(); @@ -354,11 +376,11 @@ const AnimPoseVec& AnimPoleVectorConstraint::evaluate(const AnimVariantMap& anim if (!isLeft) { deltaThetaUlnar = correctElbowForHandUlnarRadialDeviation(tipPose, midPose); } - + if (isLeft) { - fred *= -1.0f; + // fred *= -1.0f; } - + // make the dead zone PI/6.0 const float POWER = 2.0f; @@ -386,6 +408,7 @@ const AnimPoseVec& AnimPoleVectorConstraint::evaluate(const AnimVariantMap& anim } fred -= flexCorrection; } + //qCDebug(animation) << "flexCorrection anim" << flexCorrection; const float TWIST_ULNAR_DEADZONE = 0.0f; const float ULNAR_BOUNDARY_MINUS = -PI / 12.0f; @@ -425,6 +448,7 @@ const AnimPoseVec& AnimPoleVectorConstraint::evaluate(const AnimVariantMap& anim fred += ulnarCorrection; } } + //qCDebug(animation) << "ulnarCorrection anim" << ulnarCorrection; // remember direction of travel. const float TWIST_DEADZONE = PI / 2.0f; @@ -458,7 +482,7 @@ const AnimPoseVec& AnimPoleVectorConstraint::evaluate(const AnimVariantMap& anim float poleVectorTheta = theta; theta = ((180.0f - _lastTheta) / 180.0f)*PI; - qCDebug(animation) << "fake theta " << poleVectorTheta << " newly computed theta " << theta << " dot " << dot << " last dot "<< lastDot; + } diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index faddfdebb3..e476c8e5fd 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -1465,7 +1465,8 @@ void Rig::updateHands(bool leftHandEnabled, bool rightHandEnabled, bool hipsEnab int oppositeArmJointIndex = _animSkeleton->nameToJointIndex("RightArm"); if (ENABLE_POLE_VECTORS && handJointIndex >= 0 && armJointIndex >= 0 && elbowJointIndex >= 0 && oppositeArmJointIndex >= 0) { glm::vec3 poleVector; - bool usePoleVector = calculateElbowPoleVector(handJointIndex, elbowJointIndex, armJointIndex, oppositeArmJointIndex, poleVector); + //bool usePoleVector = calculateElbowPoleVector(handJointIndex, elbowJointIndex, armJointIndex, oppositeArmJointIndex, poleVector); + bool usePoleVector = calculateElbowPoleVectorOptimized(handJointIndex, elbowJointIndex, armJointIndex, true, poleVector); if (usePoleVector) { glm::vec3 sensorPoleVector = transformVectorFast(rigToSensorMatrix, poleVector); _animVars.set("leftHandPoleVectorEnabled", true); @@ -1520,7 +1521,8 @@ void Rig::updateHands(bool leftHandEnabled, bool rightHandEnabled, bool hipsEnab if (ENABLE_POLE_VECTORS && handJointIndex >= 0 && armJointIndex >= 0 && elbowJointIndex >= 0 && oppositeArmJointIndex >= 0) { glm::vec3 poleVector; - bool usePoleVector = calculateElbowPoleVector(handJointIndex, elbowJointIndex, armJointIndex, oppositeArmJointIndex, poleVector); + //bool usePoleVector = calculateElbowPoleVector(handJointIndex, elbowJointIndex, armJointIndex, oppositeArmJointIndex, poleVector); + bool usePoleVector = calculateElbowPoleVectorOptimized(handJointIndex, elbowJointIndex, armJointIndex, false, poleVector); if (usePoleVector) { glm::vec3 sensorPoleVector = transformVectorFast(rigToSensorMatrix, poleVector); _animVars.set("rightHandPoleVectorEnabled", true); @@ -1686,6 +1688,373 @@ void Rig::updateEyeJoint(int index, const glm::vec3& modelTranslation, const glm } } +bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int shoulderIndex, bool left, glm::vec3& poleVector) { + // get the default poses for the upper and lower arm + // then use this length to judge how far the hand is away from the shoulder. + // then create weights that make the elbow angle less when the x value is large in either direction. + // make the angle less when z is small. + // lower y with x center lower angle + // lower y with x out higher angle + //AnimPose oppositeArmPose = _externalPoseSet._absolutePoses[oppositeArmIndex]; + glm::vec3 referenceVector; + if (left) { + referenceVector = Vectors::UNIT_X; + } else { + referenceVector = -Vectors::UNIT_X; + } + + AnimPose handPose = _externalPoseSet._absolutePoses[handIndex]; + AnimPose shoulderPose = _externalPoseSet._absolutePoses[shoulderIndex]; + AnimPose elbowPose = _externalPoseSet._absolutePoses[elbowIndex]; + + //qCDebug(animation) << "handPose Rig " << left << "isleft" << handPose; + + AnimPose absoluteShoulderPose = getAbsoluteDefaultPose(shoulderIndex); + AnimPose absoluteHandPose = getAbsoluteDefaultPose(handIndex); + // subtract 10 centimeters from the arm length for some reason actual arm position is clamped to length - 10cm. + float defaultArmLength = glm::length(absoluteHandPose.trans() - absoluteShoulderPose.trans()); + + // calculate the reference axis and the side axis. + // Look up refVector from animVars, make sure to convert into geom space. + glm::vec3 refVector = glmExtractRotation(_rigToGeometryTransform) * elbowPose.rot() * Vectors::UNIT_X; + float refVectorLength = glm::length(refVector); + glm::vec3 unitRef = refVector / refVectorLength; + + glm::vec3 axis = shoulderPose.trans() - handPose.trans(); + float axisLength = glm::length(axis); + glm::vec3 unitAxis = axis / axisLength; + + glm::vec3 sideVector = glm::cross(unitAxis, unitRef); + float sideVectorLength = glm::length(sideVector); + + // project refVector onto axis plane + glm::vec3 refVectorProj = unitRef - glm::dot(unitRef, unitAxis) * unitAxis; + float refVectorProjLength = glm::length(refVectorProj); + + if (left) { + + //qCDebug(animation) << "rig ref proj " << refVectorProj/refVectorProjLength; // "rig reference vector: " << refVector / refVectorLength; + } + + //qCDebug(animation) << "rig reference vector projected: " << refVectorProj << " left is " << left; + + + // qCDebug(animation) << "default arm length " << defaultArmLength; + + // phi_0 is the lowest angle we can have + const float phi_0 = 15.0f; + const float zStart = 0.6f; + const float xStart = 0.1f; + // biases + //const glm::vec3 biases(30.0f, 120.0f, -30.0f); + const glm::vec3 biases(0.0f, 135.0f, 0.0f); + // weights + const float zWeightBottom = -100.0f; + //const glm::vec3 weights(-30.0f, 30.0f, 210.0f); + const glm::vec3 weights(-50.0f, 60.0f, 260.0f); + glm::vec3 armToHand = handPose.trans() - shoulderPose.trans(); + // qCDebug(animation) << "current arm length " << glm::length(armToHand); + float initial_valuesY = (fabsf(armToHand[1] / defaultArmLength) * weights[1]) + biases[1]; + float initial_valuesZ; + if (armToHand[1] > 0.0f) { + initial_valuesZ = weights[2] * glm::max(zStart - (armToHand[2] / defaultArmLength), 0.0f) * fabs(armToHand[1] / defaultArmLength); + } else { + initial_valuesZ = zWeightBottom * glm::max(zStart - (armToHand[2] / defaultArmLength), 0.0f) * fabs(armToHand[1] / defaultArmLength); + } + + //1.0f + armToHand[1]/defaultArmLength + + float initial_valuesX; + if (left) { + initial_valuesX = weights[0] * glm::max(-1.0f * (armToHand[0] / defaultArmLength) + xStart, 0.0f); + } else { + initial_valuesX = weights[0] * (((armToHand[0] / defaultArmLength) + xStart) - (0.3f) * ((1.0f + (armToHand[1] / defaultArmLength)) / 2.0f)); + } + + float theta = initial_valuesX + initial_valuesY + initial_valuesZ; + + if (theta < 13.0f) { + theta = 13.0f; + } + if (theta > 175.0f) { + theta = 175.0f; + } + + if (left) { + theta *= -1.0f; + } + + float halfTheta = theta; + + glm::quat relativeHandRotation = (elbowPose.inverse() * handPose).rot(); + + relativeHandRotation = glm::normalize(relativeHandRotation); + if (relativeHandRotation.w < 0.0f) { + relativeHandRotation.x *= -1.0f; + relativeHandRotation.y *= -1.0f; + relativeHandRotation.z *= -1.0f; + relativeHandRotation.w *= -1.0f; + } + + glm::quat twist; + glm::quat ulnarDeviation; + //swingTwistDecomposition(twistUlnarSwing, Vectors::UNIT_Z, twist, ulnarDeviation); + swingTwistDecomposition(relativeHandRotation, Vectors::UNIT_Z, twist, ulnarDeviation); + + ulnarDeviation = glm::normalize(ulnarDeviation); + if (ulnarDeviation.w < 0.0f) { + ulnarDeviation.x *= -1.0f; + ulnarDeviation.y *= -1.0f; + ulnarDeviation.z *= -1.0f; + ulnarDeviation.w *= -1.0f; + } + + glm::vec3 ulnarAxis = glm::axis(ulnarDeviation); + float ulnarDeviationTheta = glm::sign(ulnarAxis[2]) * glm::angle(ulnarDeviation); + if (left) { + if (glm::sign(ulnarDeviationTheta) != glm::sign(_ulnarRadialThetaRunningAverageLeft) && fabsf(ulnarDeviationTheta) > (5.0f * PI) / 6.0f) { + // don't allow the theta to cross the 180 degree limit. + ulnarDeviationTheta = -1.0f * ulnarDeviationTheta; + } + _ulnarRadialThetaRunningAverageLeft = 0.5f * _ulnarRadialThetaRunningAverageLeft + 0.5f * ulnarDeviationTheta; + } else { + if (glm::sign(ulnarDeviationTheta) != glm::sign(_ulnarRadialThetaRunningAverageRight) && fabsf(ulnarDeviationTheta) > (5.0f * PI) / 6.0f) { + // don't allow the theta to cross the 180 degree limit. + ulnarDeviationTheta = -1.0f * ulnarDeviationTheta; + } + _ulnarRadialThetaRunningAverageRight = 0.5f * _ulnarRadialThetaRunningAverageRight + 0.5f * ulnarDeviationTheta; + + } + //get the swingTwist of the hand to lower arm + glm::quat flex; + glm::quat twistUlnarSwing; + swingTwistDecomposition(relativeHandRotation, Vectors::UNIT_X, twistUlnarSwing, flex); + flex = glm::normalize(flex); + if (flex.w < 0.0f) { + flex.x *= -1.0f; + flex.y *= -1.0f; + flex.z *= -1.0f; + flex.w *= -1.0f; + } + + glm::vec3 flexAxis = glm::axis(flex); + + //float swingTheta = glm::angle(twistUlnarSwing); + float flexTheta = glm::sign(flexAxis[0]) * glm::angle(flex); + if (left) { + if (glm::sign(flexTheta) != glm::sign(_flexThetaRunningAverageLeft) && fabsf(flexTheta) > (5.0f * PI) / 6.0f) { + // don't allow the theta to cross the 180 degree limit. + flexTheta = -1.0f * flexTheta; + } + _flexThetaRunningAverageLeft = 0.5f * _flexThetaRunningAverageLeft + 0.5f * flexTheta; + } else { + if (glm::sign(flexTheta) != glm::sign(_flexThetaRunningAverageRight) && fabsf(flexTheta) > (5.0f * PI) / 6.0f) { + // don't allow the theta to cross the 180 degree limit. + flexTheta = -1.0f * flexTheta; + } + _flexThetaRunningAverageRight = 0.5f * _flexThetaRunningAverageRight + 0.5f * flexTheta; + + } + + + glm::quat trueTwist; + glm::quat nonTwist; + swingTwistDecomposition(relativeHandRotation, Vectors::UNIT_Y, nonTwist, trueTwist); + trueTwist = glm::normalize(trueTwist); + if (trueTwist.w < 0.0f) { + trueTwist.x *= -1.0f; + trueTwist.y *= -1.0f; + trueTwist.z *= -1.0f; + trueTwist.w *= -1.0f; + } + glm::vec3 trueTwistAxis = glm::axis(trueTwist); + float trueTwistTheta; + trueTwistTheta = glm::sign(trueTwistAxis[1]) * glm::angle(trueTwist); + if (left) { + if (glm::sign(trueTwistTheta) != glm::sign(_twistThetaRunningAverageLeft) && fabsf(trueTwistTheta) > (5.0f * PI) / 6.0f) { + // don't allow the theta to cross the 180 degree limit. + trueTwistTheta = -1.0f * trueTwistTheta; + } + _twistThetaRunningAverageLeft = 0.5f * _twistThetaRunningAverageLeft + 0.5f * trueTwistTheta; + } else { + if (glm::sign(trueTwistTheta) != glm::sign(_twistThetaRunningAverageRight) && fabsf(trueTwistTheta) > (5.0f * PI) / 6.0f) { + // don't allow the theta to cross the 180 degree limit. + trueTwistTheta = -1.0f * trueTwistTheta; + } + _twistThetaRunningAverageRight = 0.5f * _twistThetaRunningAverageRight + 0.5f * trueTwistTheta; + + } + + if (!left) { + qCDebug(animation) << "flex ave: " << (_flexThetaRunningAverageRight / PI) * 180.0f << " twist ave: " << (_twistThetaRunningAverageRight / PI) * 180.0f << " ulnar deviation ave: " << (_ulnarRadialThetaRunningAverageRight / PI) * 180.0f; + //qCDebug(animation) << "flex: " << (flexTheta / PI) * 180.0f << " twist: " << (trueTwistTheta / PI) * 180.0f << " ulnar deviation: " << (ulnarDeviationTheta / PI) * 180.0f; + + } + + // make the dead zone PI/6.0 + const float POWER = 2.0f; + const float FLEX_BOUNDARY = PI / 4.0f; + const float EXTEND_BOUNDARY = -PI / 5.0f; + float flexCorrection = 0.0f; + if (left) { + if (_flexThetaRunningAverageLeft > FLEX_BOUNDARY) { + flexCorrection = ((_flexThetaRunningAverageLeft - FLEX_BOUNDARY) / PI) * 180.0f; + } else if (_flexThetaRunningAverageLeft < EXTEND_BOUNDARY) { + flexCorrection = ((_flexThetaRunningAverageLeft - EXTEND_BOUNDARY) / PI) * 180.0f; + } + if (fabs(flexCorrection) > 30.0f) { + flexCorrection = glm::sign(flexCorrection) * 30.0f; + } + theta += flexCorrection; + } else { + if (_flexThetaRunningAverageRight > FLEX_BOUNDARY) { + flexCorrection = ((_flexThetaRunningAverageRight - FLEX_BOUNDARY) / PI) * 180.0f; + } else if (_flexThetaRunningAverageRight < EXTEND_BOUNDARY) { + flexCorrection = ((_flexThetaRunningAverageRight - EXTEND_BOUNDARY) / PI) * 180.0f; + } + if (fabs(flexCorrection) > 30.0f) { + flexCorrection = glm::sign(flexCorrection) * 30.0f; + } + theta -= flexCorrection; + } + //qCDebug(animation) << "flexCorrection rig" << flexCorrection; + + const float TWIST_ULNAR_DEADZONE = 0.0f; + const float ULNAR_BOUNDARY_MINUS = -PI / 12.0f; + const float ULNAR_BOUNDARY_PLUS = PI / 24.0f; + float ulnarDiff = 0.0f; + float ulnarCorrection = 0.0f; + if (left) { + if (_ulnarRadialThetaRunningAverageLeft > ULNAR_BOUNDARY_PLUS) { + ulnarDiff = _ulnarRadialThetaRunningAverageLeft - ULNAR_BOUNDARY_PLUS; + } else if (_ulnarRadialThetaRunningAverageLeft < ULNAR_BOUNDARY_MINUS) { + ulnarDiff = _ulnarRadialThetaRunningAverageLeft - ULNAR_BOUNDARY_MINUS; + } + if (fabs(ulnarDiff) > 0.0f) { + if (fabs(_twistThetaRunningAverageLeft) > TWIST_ULNAR_DEADZONE) { + float twistCoefficient = (fabs(_twistThetaRunningAverageLeft) / (PI / 20.0f)); + if (twistCoefficient > 1.0f) { + twistCoefficient = 1.0f; + } + + if (left) { + if (trueTwistTheta < 0.0f) { + ulnarCorrection -= glm::sign(ulnarDiff) * (fabs(ulnarDiff) / PI) * 90.0f * twistCoefficient; + } else { + ulnarCorrection += glm::sign(ulnarDiff) * (fabs(ulnarDiff) / PI) * 90.0f * twistCoefficient; + } + } else { + // right hand + if (trueTwistTheta > 0.0f) { + ulnarCorrection -= glm::sign(ulnarDiff) * (fabs(ulnarDiff) / PI) * 90.0f * twistCoefficient; + } else { + ulnarCorrection += glm::sign(ulnarDiff) * (fabs(ulnarDiff) / PI) * 90.0f * twistCoefficient; + } + + } + if (fabsf(ulnarCorrection) > 20.0f) { + ulnarCorrection = glm::sign(ulnarCorrection) * 20.0f; + } + theta += ulnarCorrection; + } + } + } else { + if (_ulnarRadialThetaRunningAverageRight > ULNAR_BOUNDARY_PLUS) { + ulnarDiff = _ulnarRadialThetaRunningAverageRight - ULNAR_BOUNDARY_PLUS; + } else if (_ulnarRadialThetaRunningAverageRight < ULNAR_BOUNDARY_MINUS) { + ulnarDiff = _ulnarRadialThetaRunningAverageRight - ULNAR_BOUNDARY_MINUS; + } + if (fabs(ulnarDiff) > 0.0f) { + if (fabs(_twistThetaRunningAverageRight) > TWIST_ULNAR_DEADZONE) { + float twistCoefficient = (fabs(_twistThetaRunningAverageRight) / (PI / 20.0f)); + if (twistCoefficient > 1.0f) { + twistCoefficient = 1.0f; + } + + if (left) { + if (trueTwistTheta < 0.0f) { + ulnarCorrection -= glm::sign(ulnarDiff) * (fabs(ulnarDiff) / PI) * 90.0f * twistCoefficient; + } else { + ulnarCorrection += glm::sign(ulnarDiff) * (fabs(ulnarDiff) / PI) * 90.0f * twistCoefficient; + } + } else { + // right hand + if (trueTwistTheta > 0.0f) { + ulnarCorrection -= glm::sign(ulnarDiff) * (fabs(ulnarDiff) / PI) * 90.0f * twistCoefficient; + } else { + ulnarCorrection += glm::sign(ulnarDiff) * (fabs(ulnarDiff) / PI) * 90.0f * twistCoefficient; + } + + } + if (fabsf(ulnarCorrection) > 20.0f) { + ulnarCorrection = glm::sign(ulnarCorrection) * 20.0f; + } + theta += ulnarCorrection; + } + } + + } + // qCDebug(animation) << "ulnarCorrection rig" << ulnarCorrection; + + // remember direction of travel. + const float TWIST_DEADZONE = PI / 2.0f; + //if (!isLeft) { + float twistCorrection = 0.0f; + if (left) { + if (_twistThetaRunningAverageLeft < -TWIST_DEADZONE) { + twistCorrection = glm::sign(_twistThetaRunningAverageLeft) * ((fabsf(_twistThetaRunningAverageLeft) - TWIST_DEADZONE) / PI) * 60.0f; + } else { + if (_twistThetaRunningAverageLeft > TWIST_DEADZONE) { + twistCorrection = glm::sign(_twistThetaRunningAverageLeft) * ((fabsf(_twistThetaRunningAverageLeft) - TWIST_DEADZONE) / PI) * 60.0f; + } + } + } else { + if (_twistThetaRunningAverageRight < -TWIST_DEADZONE) { + twistCorrection = glm::sign(_twistThetaRunningAverageRight) * ((fabsf(_twistThetaRunningAverageRight) - TWIST_DEADZONE) / PI) * 60.0f; + } else { + if (_twistThetaRunningAverageRight > TWIST_DEADZONE) { + twistCorrection = glm::sign(_twistThetaRunningAverageRight) * ((fabsf(_twistThetaRunningAverageRight) - TWIST_DEADZONE) / PI) * 60.0f; + } + } + + } + if (fabsf(twistCorrection) > 30.0f) { + theta += glm::sign(twistCorrection) * 30.0f; + } else { + theta += twistCorrection; + } + //qCDebug(animation) << "twistCorrection rig" << twistCorrection; + + //qCDebug(animation) << "theta in rig " << left << " isLeft " << theta; + //return theta; + if (left) { + _animVars.set("thetaLeft", halfTheta); + } else { + _animVars.set("thetaRight", halfTheta); + } + // convert theta back to pole vector + float lastDot = cosf(((180.0f - theta) / 180.0f)*PI); + float lastSideDot = sqrt(1.0f - (lastDot*lastDot)); + + const float MIN_LENGTH = 1.0e-4f; + if (refVectorLength > MIN_LENGTH && sideVectorLength > MIN_LENGTH) { + poleVector = lastDot * (refVectorProj / refVectorProjLength) + glm::sign(theta) * lastSideDot * (sideVector / sideVectorLength); + if (left) { + + //qCDebug(animation) << "pole vector in rig " << poleVector; + } + // + } else { + poleVector = glm::vec3(1.0f, 0.0f, 0.0f); + return false; + } + + + return true; + + +} + bool Rig::calculateElbowPoleVector(int handIndex, int elbowIndex, int armIndex, int oppositeArmIndex, glm::vec3& poleVector) const { // The resulting Pole Vector is calculated as the sum of a three vectors. // The first is the vector with direction shoulder-hand. The module of this vector is inversely proportional to the strength of the resulting Pole Vector. diff --git a/libraries/animation/src/Rig.h b/libraries/animation/src/Rig.h index 7468e9f6f9..52f2c142a8 100644 --- a/libraries/animation/src/Rig.h +++ b/libraries/animation/src/Rig.h @@ -258,6 +258,7 @@ protected: void calcAnimAlpha(float speed, const std::vector& referenceSpeeds, float* alphaOut) const; bool calculateElbowPoleVector(int handIndex, int elbowIndex, int armIndex, int oppositeArmIndex, glm::vec3& poleVector) const; + bool calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int shoulderIndex, bool left, glm::vec3& poleVector); glm::vec3 calculateKneePoleVector(int footJointIndex, int kneeJoint, int upLegIndex, int hipsIndex, const AnimPose& targetFootPose) const; glm::vec3 deflectHandFromTorso(const glm::vec3& handPosition, const HFMJointShapeInfo& hipsShapeInfo, const HFMJointShapeInfo& spineShapeInfo, const HFMJointShapeInfo& spine1ShapeInfo, const HFMJointShapeInfo& spine2ShapeInfo) const; @@ -425,6 +426,14 @@ protected: bool _computeNetworkAnimation { false }; bool _sendNetworkNode { false }; + float _twistThetaRunningAverageLeft { 0.0f }; + float _flexThetaRunningAverageLeft { 0.0f }; + float _ulnarRadialThetaRunningAverageLeft { 0.0f }; + float _twistThetaRunningAverageRight{ 0.0f }; + float _flexThetaRunningAverageRight { 0.0f }; + float _ulnarRadialThetaRunningAverageRight { 0.0f }; + float _lastTheta { 0.0f }; + AnimContext _lastContext; AnimVariantMap _lastAnimVars; From 40196dcb409d26620183f928251713805353c913 Mon Sep 17 00:00:00 2001 From: amantley Date: Thu, 14 Feb 2019 18:17:31 -0800 Subject: [PATCH 072/112] wrist action works in rig now --- libraries/animation/src/AnimPoleVectorConstraint.cpp | 4 ++-- libraries/animation/src/Rig.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libraries/animation/src/AnimPoleVectorConstraint.cpp b/libraries/animation/src/AnimPoleVectorConstraint.cpp index fa78793dd2..68e561e187 100644 --- a/libraries/animation/src/AnimPoleVectorConstraint.cpp +++ b/libraries/animation/src/AnimPoleVectorConstraint.cpp @@ -285,7 +285,7 @@ const AnimPoseVec& AnimPoleVectorConstraint::evaluate(const AnimVariantMap& anim qCDebug(animation) << " anim pole vector theta from rig right" << thetaFromRig; fred = thetaFromRig; } - + /* glm::quat relativeHandRotation = (midPose.inverse() * tipPose).rot(); relativeHandRotation = glm::normalize(relativeHandRotation); @@ -466,7 +466,7 @@ const AnimPoseVec& AnimPoleVectorConstraint::evaluate(const AnimVariantMap& anim } else { fred += twistCorrection; } - + */ _lastTheta = 0.5f * _lastTheta + 0.5f * fred; //qCDebug(animation) << "twist correction: " << twistCorrection << " flex correction: " << flexCorrection << " ulnar correction " << ulnarCorrection; diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index e476c8e5fd..3c72721816 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -2028,9 +2028,9 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s //qCDebug(animation) << "theta in rig " << left << " isLeft " << theta; //return theta; if (left) { - _animVars.set("thetaLeft", halfTheta); + _animVars.set("thetaLeft", theta); } else { - _animVars.set("thetaRight", halfTheta); + _animVars.set("thetaRight", theta); } // convert theta back to pole vector float lastDot = cosf(((180.0f - theta) / 180.0f)*PI); From f8554d10a806f2c9772e949112809a599cd244c4 Mon Sep 17 00:00:00 2001 From: Angus Antley Date: Thu, 14 Feb 2019 23:45:45 -0800 Subject: [PATCH 073/112] starting cleanup --- .../src/AnimPoleVectorConstraint.cpp | 262 +----------------- .../animation/src/AnimPoleVectorConstraint.h | 3 - libraries/animation/src/Rig.cpp | 184 +++++------- 3 files changed, 80 insertions(+), 369 deletions(-) diff --git a/libraries/animation/src/AnimPoleVectorConstraint.cpp b/libraries/animation/src/AnimPoleVectorConstraint.cpp index 68e561e187..ae4496e8e9 100644 --- a/libraries/animation/src/AnimPoleVectorConstraint.cpp +++ b/libraries/animation/src/AnimPoleVectorConstraint.cpp @@ -34,69 +34,6 @@ AnimPoleVectorConstraint::~AnimPoleVectorConstraint() { } -static float correctElbowForHandFlexionExtension(const AnimPose& hand, const AnimPose& lowerArm) { - - // first calculate the ulnar/radial deviation - // use the lower arm x-axis and the hand x-axis - glm::vec3 xAxisLowerArm = lowerArm.rot() * glm::vec3(1.0f, 0.0f, 0.0f); - glm::vec3 yAxisLowerArm = lowerArm.rot() * glm::vec3(0.0f, 1.0f, 0.0f); - glm::vec3 zAxisLowerArm = lowerArm.rot() * glm::vec3(0.0f, 0.0f, 1.0f); - glm::vec3 xAxisHand = hand.rot() * glm::vec3(1.0f, 0.0f, 0.0f); - glm::vec3 yAxisHand = hand.rot() * glm::vec3(0.0f, 1.0f, 0.0f); - - //float ulnarRadialDeviation = atan2(glm::dot(xAxisHand, xAxisLowerArm), glm::dot(xAxisHand, yAxisLowerArm)); - float flexionExtension = atan2(glm::dot(yAxisHand, zAxisLowerArm), glm::dot(yAxisHand, yAxisLowerArm)); - - //qCDebug(animation) << "flexion angle " << flexionExtension; - - - float deltaInDegrees = (flexionExtension / PI) * 180.0f; - - //qCDebug(animation) << "delta in degrees " << deltaInDegrees; - - float deltaFinal = glm::sign(deltaInDegrees) * powf(fabsf(deltaInDegrees/180.0f), 1.5f) * 180.0f * -0.3f; - return deltaInDegrees;// deltaFinal; -} - -static float correctElbowForHandUlnarRadialDeviation(const AnimPose& hand, const AnimPose& lowerArm) { - - const float DEAD_ZONE = 0.3f; - const float FILTER_EXPONENT = 2.0f; - // first calculate the ulnar/radial deviation - // use the lower arm x-axis and the hand x-axis - glm::vec3 xAxisLowerArm = lowerArm.rot() * glm::vec3(1.0f, 0.0f, 0.0f); - glm::vec3 yAxisLowerArm = lowerArm.rot() * glm::vec3(0.0f, 1.0f, 0.0f); - glm::vec3 zAxisLowerArm = lowerArm.rot() * glm::vec3(0.0f, 0.0f, 1.0f); - glm::vec3 xAxisHand = hand.rot() * glm::vec3(1.0f, 0.0f, 0.0f); - glm::vec3 yAxisHand = hand.rot() * glm::vec3(0.0f, 1.0f, 0.0f); - - float ulnarRadialDeviation = atan2(glm::dot(xAxisHand, xAxisLowerArm), glm::dot(xAxisHand, yAxisLowerArm)); - //float flexionExtension = atan2(glm::dot(yAxisHand, zAxisLowerArm), glm::dot(yAxisHand, yAxisLowerArm)); - - - - float makeForwardZeroRadians = ulnarRadialDeviation - (PI / 2.0f); - - //qCDebug(animation) << "calibrated ulnar " << makeForwardZeroRadians; - - float deltaFractionOfPi = (makeForwardZeroRadians / PI); - float deltaUlnarRadial; - if (fabsf(deltaFractionOfPi) < DEAD_ZONE) { - deltaUlnarRadial = 0.0f; - } else { - deltaUlnarRadial = (deltaFractionOfPi - glm::sign(deltaFractionOfPi) * DEAD_ZONE) / (1.0f - DEAD_ZONE); - } - - float deltaUlnarRadialDegrees = glm::sign(deltaUlnarRadial) * powf(fabsf(deltaUlnarRadial), FILTER_EXPONENT) * 180.0f; - - - - //qCDebug(animation) << "ulnar delta in degrees " << deltaUlnarRadialDegrees; - - float deltaFinal = deltaUlnarRadialDegrees; - return deltaFractionOfPi * 180.0f; // deltaFinal; -} - float AnimPoleVectorConstraint::findThetaNewWay(const glm::vec3& hand, const glm::vec3& shoulder, bool left) const { // get the default poses for the upper and lower arm // then use this length to judge how far the hand is away from the shoulder. @@ -184,8 +121,8 @@ const AnimPoseVec& AnimPoleVectorConstraint::evaluate(const AnimVariantMap& anim glm::vec3 poleVector = animVars.lookupRigToGeometryVector(_poleVectorVar, Vectors::UNIT_Z); if (_skeleton->nameToJointIndex("LeftHand") == _tipJointIndex) { - float thetaFromRig = animVars.lookup("thetaRight", 0.0f); - qCDebug(animation) << " anim pole vector theta from rig " << thetaFromRig; + //float thetaFromRig = animVars.lookup("thetaRight", 0.0f); + //qCDebug(animation) << " anim pole vector theta from rig " << thetaFromRig; } // determine if we should interpolate @@ -227,6 +164,11 @@ const AnimPoseVec& AnimPoleVectorConstraint::evaluate(const AnimVariantMap& anim glm::vec3 refVector = midPose.xformVectorFast(_referenceVector); float refVectorLength = glm::length(refVector); + if (_skeleton->nameToJointIndex("LeftHand") == _tipJointIndex) { + //qCDebug(animation) << "mid pose anim " << midPose; + //qCDebug(animation) << "ref vector anim " << refVector; + } + glm::vec3 axis = basePose.trans() - tipPose.trans(); float axisLength = glm::length(axis); glm::vec3 unitAxis = axis / axisLength; @@ -247,7 +189,7 @@ const AnimPoseVec& AnimPoleVectorConstraint::evaluate(const AnimVariantMap& anim if (refVectorLength > MIN_LENGTH && sideVectorLength > MIN_LENGTH) { poleVector = lastDot * (refVectorProj / refVectorProjLength) + glm::sign(_lastTheta) * lastSideDot * (sideVector / sideVectorLength); if (_skeleton->nameToJointIndex("LeftHand") == _tipJointIndex) { - qCDebug(animation) << " anim pole vector computed: " << poleVector; + //qCDebug(animation) << "pole vector anim: " << poleVector; } } else { poleVector = glm::vec3(1.0f, 0.0f, 0.0f); @@ -277,196 +219,15 @@ const AnimPoseVec& AnimPoleVectorConstraint::evaluate(const AnimVariantMap& anim //fred = findThetaNewWay(tipPose.trans(), basePose.trans(), isLeft); if (isLeft) { float thetaFromRig = animVars.lookup("thetaLeft", 0.0f); - qCDebug(animation) << " anim pole vector theta from rig left" << thetaFromRig; + //qCDebug(animation) << " anim pole vector theta from rig left" << thetaFromRig; fred = thetaFromRig; } else { float thetaFromRig = animVars.lookup("thetaRight", 0.0f); - qCDebug(animation) << " anim pole vector theta from rig right" << thetaFromRig; + //qCDebug(animation) << " anim pole vector theta from rig right" << thetaFromRig; fred = thetaFromRig; } - /* - glm::quat relativeHandRotation = (midPose.inverse() * tipPose).rot(); - - relativeHandRotation = glm::normalize(relativeHandRotation); - if (relativeHandRotation.w < 0.0f) { - relativeHandRotation.x *= -1.0f; - relativeHandRotation.y *= -1.0f; - relativeHandRotation.z *= -1.0f; - relativeHandRotation.w *= -1.0f; - } - - glm::quat twist; - glm::quat ulnarDeviation; - //swingTwistDecomposition(twistUlnarSwing, Vectors::UNIT_Z, twist, ulnarDeviation); - swingTwistDecomposition(relativeHandRotation, Vectors::UNIT_Z, twist, ulnarDeviation); - - ulnarDeviation = glm::normalize(ulnarDeviation); - if (ulnarDeviation.w < 0.0f) { - ulnarDeviation.x *= -1.0f; - ulnarDeviation.y *= -1.0f; - ulnarDeviation.z *= -1.0f; - ulnarDeviation.w *= -1.0f; - } - //glm::vec3 twistAxis = glm::axis(twist); - glm::vec3 ulnarAxis = glm::axis(ulnarDeviation); - //float twistTheta = glm::sign(twistAxis[1]) * glm::angle(twist); - float ulnarDeviationTheta = glm::sign(ulnarAxis[2]) * glm::angle(ulnarDeviation); - if (glm::sign(ulnarDeviationTheta) != glm::sign(_ulnarRadialThetaRunningAverage) && fabsf(ulnarDeviationTheta) >(5.0f * PI) / 6.0f) { - // don't allow the theta to cross the 180 degree limit. - ulnarDeviationTheta = -1.0f * ulnarDeviationTheta; - } - _ulnarRadialThetaRunningAverage = 0.5f * _ulnarRadialThetaRunningAverage + 0.5f * ulnarDeviationTheta; - - //get the swingTwist of the hand to lower arm - glm::quat flex; - glm::quat twistUlnarSwing; - - swingTwistDecomposition(relativeHandRotation, Vectors::UNIT_X, twistUlnarSwing, flex); - - flex = glm::normalize(flex); - if (flex.w < 0.0f) { - flex.x *= -1.0f; - flex.y *= -1.0f; - flex.z *= -1.0f; - flex.w *= -1.0f; - } - - glm::vec3 flexAxis = glm::axis(flex); - - //float swingTheta = glm::angle(twistUlnarSwing); - float flexTheta = glm::sign(flexAxis[0]) * glm::angle(flex); - if (glm::sign(flexTheta) != glm::sign(_flexThetaRunningAverage) && fabsf(flexTheta) > (5.0f * PI) / 6.0f) { - // don't allow the theta to cross the 180 degree limit. - flexTheta = -1.0f * flexTheta; - } - _flexThetaRunningAverage = 0.5f * _flexThetaRunningAverage + 0.5f * flexTheta; - - - glm::quat trueTwist; - glm::quat nonTwist; - swingTwistDecomposition(relativeHandRotation, Vectors::UNIT_Y, nonTwist, trueTwist); - trueTwist = glm::normalize(trueTwist); - if (trueTwist.w < 0.0f) { - trueTwist.x *= -1.0f; - trueTwist.y *= -1.0f; - trueTwist.z *= -1.0f; - trueTwist.w *= -1.0f; - } - glm::vec3 trueTwistAxis = glm::axis(trueTwist); - float trueTwistTheta; - trueTwistTheta = glm::sign(trueTwistAxis[1]) * glm::angle(trueTwist); - if (glm::sign(trueTwistTheta) != glm::sign(_twistThetaRunningAverage) && fabsf(trueTwistTheta) >(5.0f * PI) / 6.0f) { - // don't allow the theta to cross the 180 degree limit. - trueTwistTheta = -1.0f * trueTwistTheta; - } - - _twistThetaRunningAverage = 0.5f * _twistThetaRunningAverage + 0.5f * trueTwistTheta; - - - if (!isLeft) { - //qCDebug(animation) << "flex ave: " << (_flexThetaRunningAverage / PI) * 180.0f << " twist ave: " << (_twistThetaRunningAverage / PI) * 180.0f << " ulnar deviation ave: " << (_ulnarRadialThetaRunningAverage / PI) * 180.0f; - //qCDebug(animation) << "flex: " << (flexTheta / PI) * 180.0f << " twist: " << (trueTwistTheta / PI) * 180.0f << " ulnar deviation: " << (ulnarDeviationTheta / PI) * 180.0f; - - } - - // here is where we would do the wrist correction. - float deltaTheta = correctElbowForHandFlexionExtension(tipPose, midPose); - float deltaThetaUlnar; - if (!isLeft) { - deltaThetaUlnar = correctElbowForHandUlnarRadialDeviation(tipPose, midPose); - } - if (isLeft) { - // fred *= -1.0f; - } - - // make the dead zone PI/6.0 - - const float POWER = 2.0f; - const float FLEX_BOUNDARY = PI / 4.0f; - const float EXTEND_BOUNDARY = -PI / 5.0f; - float flexCorrection = 0.0f; - if (isLeft) { - if (_flexThetaRunningAverage > FLEX_BOUNDARY) { - flexCorrection = ((_flexThetaRunningAverage - FLEX_BOUNDARY) / PI) * 180.0f; - } else if (_flexThetaRunningAverage < EXTEND_BOUNDARY) { - flexCorrection = ((_flexThetaRunningAverage - EXTEND_BOUNDARY) / PI) * 180.0f; - } - if (fabs(flexCorrection) > 30.0f) { - flexCorrection = glm::sign(flexCorrection) * 30.0f; - } - fred += flexCorrection; - } else { - if (_flexThetaRunningAverage > FLEX_BOUNDARY) { - flexCorrection = ((_flexThetaRunningAverage - FLEX_BOUNDARY) / PI) * 180.0f; - } else if (_flexThetaRunningAverage < EXTEND_BOUNDARY) { - flexCorrection = ((_flexThetaRunningAverage - EXTEND_BOUNDARY) / PI) * 180.0f; - } - if (fabs(flexCorrection) > 30.0f) { - flexCorrection = glm::sign(flexCorrection) * 30.0f; - } - fred -= flexCorrection; - } - //qCDebug(animation) << "flexCorrection anim" << flexCorrection; - - const float TWIST_ULNAR_DEADZONE = 0.0f; - const float ULNAR_BOUNDARY_MINUS = -PI / 12.0f; - const float ULNAR_BOUNDARY_PLUS = PI / 24.0f; - float ulnarDiff = 0.0f; - float ulnarCorrection = 0.0f; - if (_ulnarRadialThetaRunningAverage > ULNAR_BOUNDARY_PLUS) { - ulnarDiff = _ulnarRadialThetaRunningAverage - ULNAR_BOUNDARY_PLUS; - } else if (_ulnarRadialThetaRunningAverage < ULNAR_BOUNDARY_MINUS) { - ulnarDiff = _ulnarRadialThetaRunningAverage - ULNAR_BOUNDARY_MINUS; - } - if(fabs(ulnarDiff) > 0.0f){ - if (fabs(_twistThetaRunningAverage) > TWIST_ULNAR_DEADZONE) { - float twistCoefficient = (fabs(_twistThetaRunningAverage) / (PI / 20.0f)); - if (twistCoefficient > 1.0f) { - twistCoefficient = 1.0f; - } - - if (isLeft) { - if (trueTwistTheta < 0.0f) { - ulnarCorrection -= glm::sign(ulnarDiff) * (fabs(ulnarDiff) / PI) * 90.0f * twistCoefficient; - } else { - ulnarCorrection += glm::sign(ulnarDiff) * (fabs(ulnarDiff) / PI) * 90.0f * twistCoefficient; - } - } else { - // right hand - if (trueTwistTheta > 0.0f) { - ulnarCorrection -= glm::sign(ulnarDiff) * (fabs(ulnarDiff) / PI) * 90.0f * twistCoefficient; - } else { - ulnarCorrection += glm::sign(ulnarDiff) * (fabs(ulnarDiff) / PI) * 90.0f * twistCoefficient; - } - - } - if (fabsf(ulnarCorrection) > 20.0f) { - ulnarCorrection = glm::sign(ulnarCorrection) * 20.0f; - } - fred += ulnarCorrection; - } - } - //qCDebug(animation) << "ulnarCorrection anim" << ulnarCorrection; - - // remember direction of travel. - const float TWIST_DEADZONE = PI / 2.0f; - //if (!isLeft) { - float twistCorrection = 0.0f; - if (_twistThetaRunningAverage < -TWIST_DEADZONE) { - twistCorrection = glm::sign(_twistThetaRunningAverage) * ((fabsf(_twistThetaRunningAverage) - TWIST_DEADZONE) / PI) * 60.0f; - } else { - if (_twistThetaRunningAverage > TWIST_DEADZONE) { - twistCorrection = glm::sign(_twistThetaRunningAverage) * ((fabsf(_twistThetaRunningAverage) - TWIST_DEADZONE) / PI) * 60.0f; - } - } - if (fabsf(twistCorrection) > 30.0f) { - fred += glm::sign(twistCorrection) * 30.0f; - } else { - fred += twistCorrection; - } - */ _lastTheta = 0.5f * _lastTheta + 0.5f * fred; //qCDebug(animation) << "twist correction: " << twistCorrection << " flex correction: " << flexCorrection << " ulnar correction " << ulnarCorrection; @@ -482,12 +243,9 @@ const AnimPoseVec& AnimPoleVectorConstraint::evaluate(const AnimVariantMap& anim float poleVectorTheta = theta; theta = ((180.0f - _lastTheta) / 180.0f)*PI; - } - - //glm::quat deltaRot = glm::angleAxis(theta, unitAxis); glm::quat deltaRot = glm::angleAxis(theta, unitAxis); diff --git a/libraries/animation/src/AnimPoleVectorConstraint.h b/libraries/animation/src/AnimPoleVectorConstraint.h index 078676d4f9..d0c80a393b 100644 --- a/libraries/animation/src/AnimPoleVectorConstraint.h +++ b/libraries/animation/src/AnimPoleVectorConstraint.h @@ -66,9 +66,6 @@ protected: float _interpAlphaVel { 0.0f }; float _interpAlpha { 0.0f }; - float _twistThetaRunningAverage { 0.0f }; - float _flexThetaRunningAverage { 0.0f }; - float _ulnarRadialThetaRunningAverage { 0.0f }; float _lastTheta { 0.0f }; AnimChain _snapshotChain; diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index 3c72721816..3ca1411ec0 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -1695,7 +1695,7 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s // make the angle less when z is small. // lower y with x center lower angle // lower y with x out higher angle - //AnimPose oppositeArmPose = _externalPoseSet._absolutePoses[oppositeArmIndex]; + glm::vec3 referenceVector; if (left) { referenceVector = Vectors::UNIT_X; @@ -1707,40 +1707,38 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s AnimPose shoulderPose = _externalPoseSet._absolutePoses[shoulderIndex]; AnimPose elbowPose = _externalPoseSet._absolutePoses[elbowIndex]; - //qCDebug(animation) << "handPose Rig " << left << "isleft" << handPose; - AnimPose absoluteShoulderPose = getAbsoluteDefaultPose(shoulderIndex); AnimPose absoluteHandPose = getAbsoluteDefaultPose(handIndex); - // subtract 10 centimeters from the arm length for some reason actual arm position is clamped to length - 10cm. float defaultArmLength = glm::length(absoluteHandPose.trans() - absoluteShoulderPose.trans()); // calculate the reference axis and the side axis. // Look up refVector from animVars, make sure to convert into geom space. - glm::vec3 refVector = glmExtractRotation(_rigToGeometryTransform) * elbowPose.rot() * Vectors::UNIT_X; + glm::vec3 refVector = (AnimPose(_rigToGeometryTransform) * elbowPose).xformVectorFast(Vectors::UNIT_X); float refVectorLength = glm::length(refVector); - glm::vec3 unitRef = refVector / refVectorLength; - glm::vec3 axis = shoulderPose.trans() - handPose.trans(); + if (left) { + //AnimPose temp(_rigToGeometryTransform); + //glm::mat4 elbowMat(elbowPose); + //AnimPose result3(_rigToGeometryTransform * elbowMat); + //AnimPose geomElbow2 = temp * elbowPose; + //qCDebug(animation) << "mid pose geom2 rig" << geomElbow2; + //qCDebug(animation) << "mid pose result rig" << result3; + //qCDebug(animation) << "ref vector rig" << refVector; + } + + AnimPose geomShoulder = AnimPose(_rigToGeometryTransform) * shoulderPose; + AnimPose geomHand = AnimPose(_rigToGeometryTransform) * handPose; + glm::vec3 axis = geomShoulder.trans() - geomHand.trans(); float axisLength = glm::length(axis); glm::vec3 unitAxis = axis / axisLength; - glm::vec3 sideVector = glm::cross(unitAxis, unitRef); + glm::vec3 sideVector = glm::cross(unitAxis, refVector); float sideVectorLength = glm::length(sideVector); // project refVector onto axis plane - glm::vec3 refVectorProj = unitRef - glm::dot(unitRef, unitAxis) * unitAxis; + glm::vec3 refVectorProj = refVector - glm::dot(refVector, unitAxis) * unitAxis; float refVectorProjLength = glm::length(refVectorProj); - if (left) { - - //qCDebug(animation) << "rig ref proj " << refVectorProj/refVectorProjLength; // "rig reference vector: " << refVector / refVectorLength; - } - - //qCDebug(animation) << "rig reference vector projected: " << refVectorProj << " left is " << left; - - - // qCDebug(animation) << "default arm length " << defaultArmLength; - // phi_0 is the lowest angle we can have const float phi_0 = 15.0f; const float zStart = 0.6f; @@ -1750,28 +1748,25 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s const glm::vec3 biases(0.0f, 135.0f, 0.0f); // weights const float zWeightBottom = -100.0f; - //const glm::vec3 weights(-30.0f, 30.0f, 210.0f); const glm::vec3 weights(-50.0f, 60.0f, 260.0f); glm::vec3 armToHand = handPose.trans() - shoulderPose.trans(); - // qCDebug(animation) << "current arm length " << glm::length(armToHand); - float initial_valuesY = (fabsf(armToHand[1] / defaultArmLength) * weights[1]) + biases[1]; - float initial_valuesZ; + float yFactor = (fabsf(armToHand[1] / defaultArmLength) * weights[1]) + biases[1]; + + float zFactor; if (armToHand[1] > 0.0f) { - initial_valuesZ = weights[2] * glm::max(zStart - (armToHand[2] / defaultArmLength), 0.0f) * fabs(armToHand[1] / defaultArmLength); + zFactor = weights[2] * glm::max(zStart - (armToHand[2] / defaultArmLength), 0.0f) * fabs(armToHand[1] / defaultArmLength); } else { - initial_valuesZ = zWeightBottom * glm::max(zStart - (armToHand[2] / defaultArmLength), 0.0f) * fabs(armToHand[1] / defaultArmLength); + zFactor = zWeightBottom * glm::max(zStart - (armToHand[2] / defaultArmLength), 0.0f) * fabs(armToHand[1] / defaultArmLength); } - //1.0f + armToHand[1]/defaultArmLength - - float initial_valuesX; + float xFactor; if (left) { - initial_valuesX = weights[0] * glm::max(-1.0f * (armToHand[0] / defaultArmLength) + xStart, 0.0f); + xFactor = weights[0] * glm::max(-1.0f * (armToHand[0] / defaultArmLength) + xStart, 0.0f); } else { - initial_valuesX = weights[0] * (((armToHand[0] / defaultArmLength) + xStart) - (0.3f) * ((1.0f + (armToHand[1] / defaultArmLength)) / 2.0f)); + xFactor = weights[0] * (((armToHand[0] / defaultArmLength) + xStart) - (0.3f) * ((1.0f + (armToHand[1] / defaultArmLength)) / 2.0f)); } - float theta = initial_valuesX + initial_valuesY + initial_valuesZ; + float theta = xFactor + yFactor + zFactor; if (theta < 13.0f) { theta = 13.0f; @@ -1784,117 +1779,93 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s theta *= -1.0f; } - float halfTheta = theta; - + // now we calculate the contribution of the hand glm::quat relativeHandRotation = (elbowPose.inverse() * handPose).rot(); - - relativeHandRotation = glm::normalize(relativeHandRotation); if (relativeHandRotation.w < 0.0f) { - relativeHandRotation.x *= -1.0f; - relativeHandRotation.y *= -1.0f; - relativeHandRotation.z *= -1.0f; - relativeHandRotation.w *= -1.0f; + relativeHandRotation *= -1.0f; } - glm::quat twist; glm::quat ulnarDeviation; - //swingTwistDecomposition(twistUlnarSwing, Vectors::UNIT_Z, twist, ulnarDeviation); - swingTwistDecomposition(relativeHandRotation, Vectors::UNIT_Z, twist, ulnarDeviation); - - ulnarDeviation = glm::normalize(ulnarDeviation); + glm::quat nonUlnarDeviation; + swingTwistDecomposition(relativeHandRotation, Vectors::UNIT_Z, nonUlnarDeviation, ulnarDeviation); if (ulnarDeviation.w < 0.0f) { - ulnarDeviation.x *= -1.0f; - ulnarDeviation.y *= -1.0f; - ulnarDeviation.z *= -1.0f; - ulnarDeviation.w *= -1.0f; + ulnarDeviation *= 1.0f; } - glm::vec3 ulnarAxis = glm::axis(ulnarDeviation); float ulnarDeviationTheta = glm::sign(ulnarAxis[2]) * glm::angle(ulnarDeviation); if (left) { - if (glm::sign(ulnarDeviationTheta) != glm::sign(_ulnarRadialThetaRunningAverageLeft) && fabsf(ulnarDeviationTheta) > (5.0f * PI) / 6.0f) { + if (glm::sign(ulnarDeviationTheta) != glm::sign(_ulnarRadialThetaRunningAverageLeft) && fabsf(ulnarDeviationTheta) > (PI / 2.0f)) { // don't allow the theta to cross the 180 degree limit. ulnarDeviationTheta = -1.0f * ulnarDeviationTheta; } + // put some smoothing on the theta _ulnarRadialThetaRunningAverageLeft = 0.5f * _ulnarRadialThetaRunningAverageLeft + 0.5f * ulnarDeviationTheta; } else { - if (glm::sign(ulnarDeviationTheta) != glm::sign(_ulnarRadialThetaRunningAverageRight) && fabsf(ulnarDeviationTheta) > (5.0f * PI) / 6.0f) { + if (glm::sign(ulnarDeviationTheta) != glm::sign(_ulnarRadialThetaRunningAverageRight) && fabsf(ulnarDeviationTheta) > (PI / 2.0f)) { // don't allow the theta to cross the 180 degree limit. ulnarDeviationTheta = -1.0f * ulnarDeviationTheta; } + // put some smoothing on the theta _ulnarRadialThetaRunningAverageRight = 0.5f * _ulnarRadialThetaRunningAverageRight + 0.5f * ulnarDeviationTheta; - } - //get the swingTwist of the hand to lower arm + + //get the flex/extension of the wrist rotation glm::quat flex; - glm::quat twistUlnarSwing; - swingTwistDecomposition(relativeHandRotation, Vectors::UNIT_X, twistUlnarSwing, flex); - flex = glm::normalize(flex); + glm::quat nonFlex; + swingTwistDecomposition(relativeHandRotation, Vectors::UNIT_X, nonFlex, flex); if (flex.w < 0.0f) { - flex.x *= -1.0f; - flex.y *= -1.0f; - flex.z *= -1.0f; - flex.w *= -1.0f; + flex *= 1.0f; } - glm::vec3 flexAxis = glm::axis(flex); - - //float swingTheta = glm::angle(twistUlnarSwing); float flexTheta = glm::sign(flexAxis[0]) * glm::angle(flex); + if (left) { - if (glm::sign(flexTheta) != glm::sign(_flexThetaRunningAverageLeft) && fabsf(flexTheta) > (5.0f * PI) / 6.0f) { + if (glm::sign(flexTheta) != glm::sign(_flexThetaRunningAverageLeft) && fabsf(flexTheta) > (PI / 2.0f)) { // don't allow the theta to cross the 180 degree limit. flexTheta = -1.0f * flexTheta; } + // put some smoothing on the theta _flexThetaRunningAverageLeft = 0.5f * _flexThetaRunningAverageLeft + 0.5f * flexTheta; } else { - if (glm::sign(flexTheta) != glm::sign(_flexThetaRunningAverageRight) && fabsf(flexTheta) > (5.0f * PI) / 6.0f) { + if (glm::sign(flexTheta) != glm::sign(_flexThetaRunningAverageRight) && fabsf(flexTheta) > (PI / 2.0f)) { // don't allow the theta to cross the 180 degree limit. flexTheta = -1.0f * flexTheta; } + // put some smoothing on the theta _flexThetaRunningAverageRight = 0.5f * _flexThetaRunningAverageRight + 0.5f * flexTheta; - } - - glm::quat trueTwist; + glm::quat twist; glm::quat nonTwist; - swingTwistDecomposition(relativeHandRotation, Vectors::UNIT_Y, nonTwist, trueTwist); - trueTwist = glm::normalize(trueTwist); - if (trueTwist.w < 0.0f) { - trueTwist.x *= -1.0f; - trueTwist.y *= -1.0f; - trueTwist.z *= -1.0f; - trueTwist.w *= -1.0f; + swingTwistDecomposition(relativeHandRotation, Vectors::UNIT_Y, nonTwist, twist); + if (twist.w < 0.0f) { + twist *= 1.0f; } - glm::vec3 trueTwistAxis = glm::axis(trueTwist); - float trueTwistTheta; - trueTwistTheta = glm::sign(trueTwistAxis[1]) * glm::angle(trueTwist); + glm::vec3 trueTwistAxis = glm::axis(twist); + float trueTwistTheta = glm::sign(trueTwistAxis[1]) * glm::angle(twist); if (left) { - if (glm::sign(trueTwistTheta) != glm::sign(_twistThetaRunningAverageLeft) && fabsf(trueTwistTheta) > (5.0f * PI) / 6.0f) { + if (glm::sign(trueTwistTheta) != glm::sign(_twistThetaRunningAverageLeft) && fabsf(trueTwistTheta) > (PI / 2.0f)) { // don't allow the theta to cross the 180 degree limit. trueTwistTheta = -1.0f * trueTwistTheta; } + // put some smoothing on the theta _twistThetaRunningAverageLeft = 0.5f * _twistThetaRunningAverageLeft + 0.5f * trueTwistTheta; } else { - if (glm::sign(trueTwistTheta) != glm::sign(_twistThetaRunningAverageRight) && fabsf(trueTwistTheta) > (5.0f * PI) / 6.0f) { + if (glm::sign(trueTwistTheta) != glm::sign(_twistThetaRunningAverageRight) && fabsf(trueTwistTheta) > (PI / 2.0f)) { // don't allow the theta to cross the 180 degree limit. trueTwistTheta = -1.0f * trueTwistTheta; } + // put some smoothing on the theta _twistThetaRunningAverageRight = 0.5f * _twistThetaRunningAverageRight + 0.5f * trueTwistTheta; - } if (!left) { qCDebug(animation) << "flex ave: " << (_flexThetaRunningAverageRight / PI) * 180.0f << " twist ave: " << (_twistThetaRunningAverageRight / PI) * 180.0f << " ulnar deviation ave: " << (_ulnarRadialThetaRunningAverageRight / PI) * 180.0f; - //qCDebug(animation) << "flex: " << (flexTheta / PI) * 180.0f << " twist: " << (trueTwistTheta / PI) * 180.0f << " ulnar deviation: " << (ulnarDeviationTheta / PI) * 180.0f; - } - - // make the dead zone PI/6.0 + const float POWER = 2.0f; - const float FLEX_BOUNDARY = PI / 4.0f; - const float EXTEND_BOUNDARY = -PI / 5.0f; + const float FLEX_BOUNDARY = PI / 5.0f; + const float EXTEND_BOUNDARY = -PI / 6.0f; float flexCorrection = 0.0f; if (left) { if (_flexThetaRunningAverageLeft > FLEX_BOUNDARY) { @@ -1917,7 +1888,7 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s } theta -= flexCorrection; } - //qCDebug(animation) << "flexCorrection rig" << flexCorrection; + qCDebug(animation) << "flexCorrection rig" << flexCorrection; const float TWIST_ULNAR_DEADZONE = 0.0f; const float ULNAR_BOUNDARY_MINUS = -PI / 12.0f; @@ -1936,7 +1907,6 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s if (twistCoefficient > 1.0f) { twistCoefficient = 1.0f; } - if (left) { if (trueTwistTheta < 0.0f) { ulnarCorrection -= glm::sign(ulnarDiff) * (fabs(ulnarDiff) / PI) * 90.0f * twistCoefficient; @@ -1950,7 +1920,6 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s } else { ulnarCorrection += glm::sign(ulnarDiff) * (fabs(ulnarDiff) / PI) * 90.0f * twistCoefficient; } - } if (fabsf(ulnarCorrection) > 20.0f) { ulnarCorrection = glm::sign(ulnarCorrection) * 20.0f; @@ -1970,7 +1939,6 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s if (twistCoefficient > 1.0f) { twistCoefficient = 1.0f; } - if (left) { if (trueTwistTheta < 0.0f) { ulnarCorrection -= glm::sign(ulnarDiff) * (fabs(ulnarDiff) / PI) * 90.0f * twistCoefficient; @@ -1984,7 +1952,6 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s } else { ulnarCorrection += glm::sign(ulnarDiff) * (fabs(ulnarDiff) / PI) * 90.0f * twistCoefficient; } - } if (fabsf(ulnarCorrection) > 20.0f) { ulnarCorrection = glm::sign(ulnarCorrection) * 20.0f; @@ -1992,41 +1959,31 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s theta += ulnarCorrection; } } - } - // qCDebug(animation) << "ulnarCorrection rig" << ulnarCorrection; + qCDebug(animation) << "ulnarCorrection rig" << ulnarCorrection; // remember direction of travel. - const float TWIST_DEADZONE = PI / 2.0f; + const float TWIST_DEADZONE = (4 * PI) / 9.0f; //if (!isLeft) { float twistCorrection = 0.0f; if (left) { - if (_twistThetaRunningAverageLeft < -TWIST_DEADZONE) { - twistCorrection = glm::sign(_twistThetaRunningAverageLeft) * ((fabsf(_twistThetaRunningAverageLeft) - TWIST_DEADZONE) / PI) * 60.0f; - } else { - if (_twistThetaRunningAverageLeft > TWIST_DEADZONE) { - twistCorrection = glm::sign(_twistThetaRunningAverageLeft) * ((fabsf(_twistThetaRunningAverageLeft) - TWIST_DEADZONE) / PI) * 60.0f; - } - } + if (fabsf(_twistThetaRunningAverageLeft) > TWIST_DEADZONE) { + twistCorrection = glm::sign(_twistThetaRunningAverageLeft) * ((fabsf(_twistThetaRunningAverageLeft) - TWIST_DEADZONE) / PI) * 80.0f; + } } else { - if (_twistThetaRunningAverageRight < -TWIST_DEADZONE) { - twistCorrection = glm::sign(_twistThetaRunningAverageRight) * ((fabsf(_twistThetaRunningAverageRight) - TWIST_DEADZONE) / PI) * 60.0f; - } else { - if (_twistThetaRunningAverageRight > TWIST_DEADZONE) { - twistCorrection = glm::sign(_twistThetaRunningAverageRight) * ((fabsf(_twistThetaRunningAverageRight) - TWIST_DEADZONE) / PI) * 60.0f; - } - } - + if (fabsf(_twistThetaRunningAverageRight) > TWIST_DEADZONE) { + twistCorrection = glm::sign(_twistThetaRunningAverageRight) * ((fabsf(_twistThetaRunningAverageRight) - TWIST_DEADZONE) / PI) * 80.0f; + } } if (fabsf(twistCorrection) > 30.0f) { theta += glm::sign(twistCorrection) * 30.0f; } else { theta += twistCorrection; } - //qCDebug(animation) << "twistCorrection rig" << twistCorrection; + qCDebug(animation) << "twistCorrection rig" << twistCorrection; + + // put final global limiter here....... - //qCDebug(animation) << "theta in rig " << left << " isLeft " << theta; - //return theta; if (left) { _animVars.set("thetaLeft", theta); } else { @@ -2040,7 +1997,6 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s if (refVectorLength > MIN_LENGTH && sideVectorLength > MIN_LENGTH) { poleVector = lastDot * (refVectorProj / refVectorProjLength) + glm::sign(theta) * lastSideDot * (sideVector / sideVectorLength); if (left) { - //qCDebug(animation) << "pole vector in rig " << poleVector; } // From 382a03929e77ef1d5ce8ff9ef60e601f1007ee64 Mon Sep 17 00:00:00 2001 From: Angus Antley Date: Fri, 15 Feb 2019 07:06:43 -0800 Subject: [PATCH 074/112] changed back to regular 2 bone Ik for arms in json and cleaned up rig.cpp and polevector constraint --- .../avatar-animation_withSplineIKNode.json | 4 +- .../src/AnimPoleVectorConstraint.cpp | 124 +----------------- libraries/animation/src/Rig.cpp | 48 +++++-- libraries/animation/src/Rig.h | 3 +- 4 files changed, 46 insertions(+), 133 deletions(-) diff --git a/interface/resources/avatar/avatar-animation_withSplineIKNode.json b/interface/resources/avatar/avatar-animation_withSplineIKNode.json index 9fd64860bd..b1f198c52c 100644 --- a/interface/resources/avatar/avatar-animation_withSplineIKNode.json +++ b/interface/resources/avatar/avatar-animation_withSplineIKNode.json @@ -129,7 +129,7 @@ "children": [ { "id": "rightHandIK", - "type": "armIK", + "type": "twoBoneIK", "data": { "alpha": 1.0, "enabled": false, @@ -159,7 +159,7 @@ "children": [ { "id": "leftHandIK", - "type": "armIK", + "type": "twoBoneIK", "data": { "alpha": 1.0, "enabled": false, diff --git a/libraries/animation/src/AnimPoleVectorConstraint.cpp b/libraries/animation/src/AnimPoleVectorConstraint.cpp index ae4496e8e9..d575ddabe4 100644 --- a/libraries/animation/src/AnimPoleVectorConstraint.cpp +++ b/libraries/animation/src/AnimPoleVectorConstraint.cpp @@ -34,64 +34,6 @@ AnimPoleVectorConstraint::~AnimPoleVectorConstraint() { } -float AnimPoleVectorConstraint::findThetaNewWay(const glm::vec3& hand, const glm::vec3& shoulder, bool left) const { - // get the default poses for the upper and lower arm - // then use this length to judge how far the hand is away from the shoulder. - // then create weights that make the elbow angle less when the x value is large in either direction. - // make the angle less when z is small. - // lower y with x center lower angle - // lower y with x out higher angle - AnimPose shoulderPose = _skeleton->getAbsoluteDefaultPose(_skeleton->nameToJointIndex("RightShoulder")); - AnimPose handPose = _skeleton->getAbsoluteDefaultPose(_skeleton->nameToJointIndex("RightHand")); - // subtract 10 centimeters from the arm length for some reason actual arm position is clamped to length - 10cm. - float defaultArmLength = glm::length( handPose.trans() - shoulderPose.trans() ) - 10.0f; - // qCDebug(animation) << "default arm length " << defaultArmLength; - - // phi_0 is the lowest angle we can have - const float phi_0 = 15.0f; - const float zStart = 0.6f; - const float xStart = 0.1f; - // biases - //const glm::vec3 biases(30.0f, 120.0f, -30.0f); - const glm::vec3 biases(0.0f, 135.0f, 0.0f); - // weights - const float zWeightBottom = -100.0f; - //const glm::vec3 weights(-30.0f, 30.0f, 210.0f); - const glm::vec3 weights(-50.0f, 60.0f, 260.0f); - glm::vec3 armToHand = hand - shoulder; - // qCDebug(animation) << "current arm length " << glm::length(armToHand); - float initial_valuesY = (fabsf(armToHand[1] / defaultArmLength) * weights[1]) + biases[1]; - float initial_valuesZ; - if (armToHand[1] > 0.0f) { - initial_valuesZ = weights[2] * glm::max(zStart - (armToHand[2] / defaultArmLength), 0.0f) * fabs(armToHand[1] / defaultArmLength); - } else { - initial_valuesZ = zWeightBottom * glm::max(zStart - (armToHand[2] / defaultArmLength), 0.0f) * fabs(armToHand[1] / defaultArmLength); - } - - //1.0f + armToHand[1]/defaultArmLength - - float initial_valuesX; - if (left) { - initial_valuesX = weights[0] * glm::max(-1.0f * (armToHand[0] / defaultArmLength) + xStart, 0.0f); - } else { - initial_valuesX = weights[0] * (((armToHand[0] / defaultArmLength) + xStart) - (0.3f) * ((1.0f + (armToHand[1] / defaultArmLength))/2.0f)); - } - - float theta = initial_valuesX + initial_valuesY + initial_valuesZ; - - if (theta < 13.0f) { - theta = 13.0f; - } - if (theta > 175.0f) { - theta = 175.0f; - } - - if (!left) { - //qCDebug(animation) << "relative hand x " << initial_valuesX << " y " << initial_valuesY << " z " << initial_valuesZ << "theta value for pole vector is " << theta; - } - return theta; -} - const AnimPoseVec& AnimPoleVectorConstraint::evaluate(const AnimVariantMap& animVars, const AnimContext& context, float dt, AnimVariantMap& triggersOut) { assert(_children.size() == 1); @@ -114,13 +56,9 @@ const AnimPoseVec& AnimPoleVectorConstraint::evaluate(const AnimVariantMap& anim _poses = underPoses; } - - - // Look up poleVector from animVars, make sure to convert into geom space. glm::vec3 poleVector = animVars.lookupRigToGeometryVector(_poleVectorVar, Vectors::UNIT_Z); if (_skeleton->nameToJointIndex("LeftHand") == _tipJointIndex) { - //float thetaFromRig = animVars.lookup("thetaRight", 0.0f); //qCDebug(animation) << " anim pole vector theta from rig " << thetaFromRig; } @@ -164,11 +102,6 @@ const AnimPoseVec& AnimPoleVectorConstraint::evaluate(const AnimVariantMap& anim glm::vec3 refVector = midPose.xformVectorFast(_referenceVector); float refVectorLength = glm::length(refVector); - if (_skeleton->nameToJointIndex("LeftHand") == _tipJointIndex) { - //qCDebug(animation) << "mid pose anim " << midPose; - //qCDebug(animation) << "ref vector anim " << refVector; - } - glm::vec3 axis = basePose.trans() - tipPose.trans(); float axisLength = glm::length(axis); glm::vec3 unitAxis = axis / axisLength; @@ -180,22 +113,6 @@ const AnimPoseVec& AnimPoleVectorConstraint::evaluate(const AnimVariantMap& anim glm::vec3 refVectorProj = refVector - glm::dot(refVector, unitAxis) * unitAxis; float refVectorProjLength = glm::length(refVectorProj); - float lastDot; - if ((_skeleton->nameToJointIndex("RightHand") == _tipJointIndex) || (_skeleton->nameToJointIndex("LeftHand") == _tipJointIndex)) { - //fake pole vector computation. - lastDot = cosf(((180.0f - _lastTheta) / 180.0f)*PI); - float lastSideDot = sqrt(1.0f - (lastDot*lastDot)); - glm::vec3 pretendPoleVector; - if (refVectorLength > MIN_LENGTH && sideVectorLength > MIN_LENGTH) { - poleVector = lastDot * (refVectorProj / refVectorProjLength) + glm::sign(_lastTheta) * lastSideDot * (sideVector / sideVectorLength); - if (_skeleton->nameToJointIndex("LeftHand") == _tipJointIndex) { - //qCDebug(animation) << "pole vector anim: " << poleVector; - } - } else { - poleVector = glm::vec3(1.0f, 0.0f, 0.0f); - } - } - // project poleVector on plane formed by axis. glm::vec3 poleVectorProj = poleVector - glm::dot(poleVector, unitAxis) * unitAxis; float poleVectorProjLength = glm::length(poleVectorProj); @@ -208,45 +125,16 @@ const AnimPoseVec& AnimPoleVectorConstraint::evaluate(const AnimVariantMap& anim float sideDot = glm::dot(poleVector, sideVector); float theta = copysignf(1.0f, sideDot) * acosf(dot); - float fred; + // overwrite theta if we are using optimized code if ((_skeleton->nameToJointIndex("RightHand") == _tipJointIndex) || (_skeleton->nameToJointIndex("LeftHand") == _tipJointIndex)) { - //qCDebug(animation) << "theta from the old code " << theta; - bool isLeft = false; + if (_skeleton->nameToJointIndex("LeftHand") == _tipJointIndex) { - isLeft = true; + theta = animVars.lookup("thetaLeftElbow", 0.0f); + } else if (_skeleton->nameToJointIndex("RightHand") == _tipJointIndex) { + theta = animVars.lookup("thetaRightElbow", 0.0f); } - //qCDebug(animation) << "hand pose anim pole vector: " << isLeft << " isLeft " << tipPose; - //fred = findThetaNewWay(tipPose.trans(), basePose.trans(), isLeft); - if (isLeft) { - float thetaFromRig = animVars.lookup("thetaLeft", 0.0f); - //qCDebug(animation) << " anim pole vector theta from rig left" << thetaFromRig; - fred = thetaFromRig; - - } else { - float thetaFromRig = animVars.lookup("thetaRight", 0.0f); - //qCDebug(animation) << " anim pole vector theta from rig right" << thetaFromRig; - fred = thetaFromRig; - } - - _lastTheta = 0.5f * _lastTheta + 0.5f * fred; - - //qCDebug(animation) << "twist correction: " << twistCorrection << " flex correction: " << flexCorrection << " ulnar correction " << ulnarCorrection; - - if (fabsf(_lastTheta) < 50.0f) { - if (fabsf(_lastTheta) < 50.0f) { - _lastTheta = glm::sign(_lastTheta) * 50.0f; - } - } - if (fabsf(_lastTheta) > 175.0f) { - _lastTheta = glm::sign(_lastTheta) * 175.0f; - } - - float poleVectorTheta = theta; - theta = ((180.0f - _lastTheta) / 180.0f)*PI; - } - //glm::quat deltaRot = glm::angleAxis(theta, unitAxis); glm::quat deltaRot = glm::angleAxis(theta, unitAxis); // transform result back into parent relative frame. @@ -334,8 +222,6 @@ const AnimPoseVec& AnimPoleVectorConstraint::evaluate(const AnimVariantMap& anim return _poses; } - - // for AnimDebugDraw rendering const AnimPoseVec& AnimPoleVectorConstraint::getPosesInternal() const { return _poses; diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index 3ca1411ec0..d1b39bf049 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -1692,7 +1692,7 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s // get the default poses for the upper and lower arm // then use this length to judge how far the hand is away from the shoulder. // then create weights that make the elbow angle less when the x value is large in either direction. - // make the angle less when z is small. + // make the angle less when z is small. // lower y with x center lower angle // lower y with x out higher angle @@ -1744,14 +1744,13 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s const float zStart = 0.6f; const float xStart = 0.1f; // biases - //const glm::vec3 biases(30.0f, 120.0f, -30.0f); const glm::vec3 biases(0.0f, 135.0f, 0.0f); // weights const float zWeightBottom = -100.0f; const glm::vec3 weights(-50.0f, 60.0f, 260.0f); glm::vec3 armToHand = handPose.trans() - shoulderPose.trans(); float yFactor = (fabsf(armToHand[1] / defaultArmLength) * weights[1]) + biases[1]; - + float zFactor; if (armToHand[1] > 0.0f) { zFactor = weights[2] * glm::max(zStart - (armToHand[2] / defaultArmLength), 0.0f) * fabs(armToHand[1] / defaultArmLength); @@ -1888,7 +1887,6 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s } theta -= flexCorrection; } - qCDebug(animation) << "flexCorrection rig" << flexCorrection; const float TWIST_ULNAR_DEADZONE = 0.0f; const float ULNAR_BOUNDARY_MINUS = -PI / 12.0f; @@ -1960,7 +1958,6 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s } } } - qCDebug(animation) << "ulnarCorrection rig" << ulnarCorrection; // remember direction of travel. const float TWIST_DEADZONE = (4 * PI) / 9.0f; @@ -1969,26 +1966,55 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s if (left) { if (fabsf(_twistThetaRunningAverageLeft) > TWIST_DEADZONE) { twistCorrection = glm::sign(_twistThetaRunningAverageLeft) * ((fabsf(_twistThetaRunningAverageLeft) - TWIST_DEADZONE) / PI) * 80.0f; - } + } } else { if (fabsf(_twistThetaRunningAverageRight) > TWIST_DEADZONE) { twistCorrection = glm::sign(_twistThetaRunningAverageRight) * ((fabsf(_twistThetaRunningAverageRight) - TWIST_DEADZONE) / PI) * 80.0f; - } + } } if (fabsf(twistCorrection) > 30.0f) { theta += glm::sign(twistCorrection) * 30.0f; } else { theta += twistCorrection; } - qCDebug(animation) << "twistCorrection rig" << twistCorrection; - // put final global limiter here....... + //qCDebug(animation) << "twist correction: " << twistCorrection << " flex correction: " << flexCorrection << " ulnar correction " << ulnarCorrection; + // global limiting if (left) { - _animVars.set("thetaLeft", theta); + // final global smoothing + _lastThetaLeft = 0.5f * _lastThetaLeft + 0.5f * theta; + + if (fabsf(_lastThetaLeft) < 50.0f) { + if (fabsf(_lastThetaLeft) < 50.0f) { + _lastThetaLeft = glm::sign(_lastThetaLeft) * 50.0f; + } + } + if (fabsf(_lastThetaLeft) > 175.0f) { + _lastThetaLeft = glm::sign(_lastThetaLeft) * 175.0f; + } + // convert to radians and make 180 0 to match pole vector theta + float thetaRadians = ((180.0f - _lastThetaLeft) / 180.0f)*PI; + _animVars.set("thetaLeftElbow", thetaRadians); + } else { - _animVars.set("thetaRight", theta); + // final global smoothing + _lastThetaRight = 0.5f * _lastThetaRight + 0.5f * theta; + + if (fabsf(_lastThetaRight) < 50.0f) { + if (fabsf(_lastThetaRight) < 50.0f) { + _lastThetaRight = glm::sign(_lastThetaRight) * 50.0f; + } + } + if (fabsf(_lastThetaRight) > 175.0f) { + _lastThetaRight = glm::sign(_lastThetaRight) * 175.0f; + } + // convert to radians and make 180 0 to match pole vector theta + float thetaRadians = ((180.0f - _lastThetaRight) / 180.0f)*PI; + _animVars.set("thetaRightElbow", thetaRadians); } + + // remove this if inaccurate // convert theta back to pole vector float lastDot = cosf(((180.0f - theta) / 180.0f)*PI); float lastSideDot = sqrt(1.0f - (lastDot*lastDot)); diff --git a/libraries/animation/src/Rig.h b/libraries/animation/src/Rig.h index 52f2c142a8..693aa732fa 100644 --- a/libraries/animation/src/Rig.h +++ b/libraries/animation/src/Rig.h @@ -432,7 +432,8 @@ protected: float _twistThetaRunningAverageRight{ 0.0f }; float _flexThetaRunningAverageRight { 0.0f }; float _ulnarRadialThetaRunningAverageRight { 0.0f }; - float _lastTheta { 0.0f }; + float _lastThetaLeft { 0.0f }; + float _lastThetaRight { 0.0f }; AnimContext _lastContext; AnimVariantMap _lastAnimVars; From 07af2c525e359abb87bb2861996cda701c2c80d0 Mon Sep 17 00:00:00 2001 From: Angus Antley Date: Fri, 15 Feb 2019 07:31:28 -0800 Subject: [PATCH 075/112] tweaked ulnar radial limit and extend limit --- libraries/animation/src/Rig.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index d1b39bf049..6c2851ec17 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -1863,14 +1863,14 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s } const float POWER = 2.0f; - const float FLEX_BOUNDARY = PI / 5.0f; - const float EXTEND_BOUNDARY = -PI / 6.0f; + const float FLEX_BOUNDARY = PI / 6.0f; + const float EXTEND_BOUNDARY = -PI / 4.0f; float flexCorrection = 0.0f; if (left) { if (_flexThetaRunningAverageLeft > FLEX_BOUNDARY) { - flexCorrection = ((_flexThetaRunningAverageLeft - FLEX_BOUNDARY) / PI) * 180.0f; + flexCorrection = ((_flexThetaRunningAverageLeft - FLEX_BOUNDARY) / PI) * 90.0f; } else if (_flexThetaRunningAverageLeft < EXTEND_BOUNDARY) { - flexCorrection = ((_flexThetaRunningAverageLeft - EXTEND_BOUNDARY) / PI) * 180.0f; + flexCorrection = ((_flexThetaRunningAverageLeft - EXTEND_BOUNDARY) / PI) * 90.0f; } if (fabs(flexCorrection) > 30.0f) { flexCorrection = glm::sign(flexCorrection) * 30.0f; @@ -1889,8 +1889,8 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s } const float TWIST_ULNAR_DEADZONE = 0.0f; - const float ULNAR_BOUNDARY_MINUS = -PI / 12.0f; - const float ULNAR_BOUNDARY_PLUS = PI / 24.0f; + const float ULNAR_BOUNDARY_MINUS = -PI / 6.0f; + const float ULNAR_BOUNDARY_PLUS = PI / 6.0f; float ulnarDiff = 0.0f; float ulnarCorrection = 0.0f; if (left) { @@ -1907,16 +1907,16 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s } if (left) { if (trueTwistTheta < 0.0f) { - ulnarCorrection -= glm::sign(ulnarDiff) * (fabs(ulnarDiff) / PI) * 90.0f * twistCoefficient; + ulnarCorrection -= glm::sign(ulnarDiff) * (fabs(ulnarDiff) / PI) * 40.0f * twistCoefficient; } else { - ulnarCorrection += glm::sign(ulnarDiff) * (fabs(ulnarDiff) / PI) * 90.0f * twistCoefficient; + ulnarCorrection += glm::sign(ulnarDiff) * (fabs(ulnarDiff) / PI) * 40.0f * twistCoefficient; } } else { // right hand if (trueTwistTheta > 0.0f) { - ulnarCorrection -= glm::sign(ulnarDiff) * (fabs(ulnarDiff) / PI) * 90.0f * twistCoefficient; + ulnarCorrection -= glm::sign(ulnarDiff) * (fabs(ulnarDiff) / PI) * 40.0f * twistCoefficient; } else { - ulnarCorrection += glm::sign(ulnarDiff) * (fabs(ulnarDiff) / PI) * 90.0f * twistCoefficient; + ulnarCorrection += glm::sign(ulnarDiff) * (fabs(ulnarDiff) / PI) * 40.0f * twistCoefficient; } } if (fabsf(ulnarCorrection) > 20.0f) { From 98c321c71863ddf1e2c1ca6703c41834458c683c Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Fri, 15 Feb 2019 09:40:49 -0700 Subject: [PATCH 076/112] Fix warnings --- interface/src/avatar/MyAvatar.cpp | 10 +- interface/src/avatar/MyAvatar.h | 4 +- libraries/animation/src/Flow.cpp | 164 ++++++++++++------------------ libraries/animation/src/Flow.h | 28 ++--- 4 files changed, 81 insertions(+), 125 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 5880f4ee3c..96fdd6a9e1 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -5322,15 +5322,17 @@ void MyAvatar::addAvatarHandsToFlow(const std::shared_ptr& otherAvatar) } } -void MyAvatar::useFlow(const QVariantMap& physicsConfig, const QVariantMap& collisionsConfig) { +void MyAvatar::useFlow(bool isActive, bool isCollidable, const QVariantMap& physicsConfig, const QVariantMap& collisionsConfig) { if (_skeletonModel->isLoaded()) { auto &flow = _skeletonModel->getRig().getFlow(); - flow.init(); + flow.init(isActive, isCollidable); + auto &collisionSystem = flow.getCollisionSystem(); + collisionSystem.setActive(isCollidable); auto physicsGroups = physicsConfig.keys(); if (physicsGroups.size() > 0) { for (auto &groupName : physicsGroups) { auto &settings = physicsConfig[groupName].toMap(); - FlowPhysicsSettings physicsSettings = flow.getPhysicsSettingsForGroup(groupName); + FlowPhysicsSettings physicsSettings; if (settings.contains("active")) { physicsSettings._active = settings["active"].toBool(); } @@ -5357,7 +5359,6 @@ void MyAvatar::useFlow(const QVariantMap& physicsConfig, const QVariantMap& coll } auto collisionJoints = collisionsConfig.keys(); if (collisionJoints.size() > 0) { - auto &collisionSystem = flow.getCollisionSystem(); collisionSystem.resetCollisions(); for (auto &jointName : collisionJoints) { int jointIndex = getJointIndex(jointName); @@ -5372,7 +5373,6 @@ void MyAvatar::useFlow(const QVariantMap& physicsConfig, const QVariantMap& coll } collisionSystem.addCollisionSphere(jointIndex, collisionsSettings); } - } } } diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index f98ae9208a..2c8dedd430 100755 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -1189,12 +1189,14 @@ public: /**jsdoc * Init flow simulation on avatar. * @function MyAvatar.useFlow + * @param {boolean} - Set to true to activate flow simulation. + * @param {boolean} - Set to true to activate collisions. * @param {Object} physicsConfig - object with the customized physic parameters * i.e. {"hair": {"active": true, "stiffness": 0.0, "radius": 0.04, "gravity": -0.035, "damping": 0.8, "inertia": 0.8, "delta": 0.35}} * @param {Object} collisionsConfig - object with the customized collision parameters * i.e. {"Spine2": {"type": "sphere", "radius": 0.14, "offset": {"x": 0.0, "y": 0.2, "z": 0.0}}} */ - Q_INVOKABLE void useFlow(const QVariantMap& flowConfig = QVariantMap(), const QVariantMap& collisionsConfig = QVariantMap()); + Q_INVOKABLE void useFlow(bool isActive, bool isCollidable, const QVariantMap& physicsConfig = QVariantMap(), const QVariantMap& collisionsConfig = QVariantMap()); public slots: diff --git a/libraries/animation/src/Flow.cpp b/libraries/animation/src/Flow.cpp index 3db0068434..607b2775e0 100644 --- a/libraries/animation/src/Flow.cpp +++ b/libraries/animation/src/Flow.cpp @@ -93,8 +93,7 @@ FlowCollisionResult FlowCollisionSystem::computeCollision(const std::vector FlowCollisionSystem::checkFlowThreadCollisions( return results; }; -int FlowCollisionSystem::findSelfCollisionWithJoint(int jointIndex) { - for (size_t i = 0; i < _selfCollisions.size(); i++) { - if (_selfCollisions[i]._jointIndex == jointIndex) { - return (int)i; - } - } - return -1; -}; - -void FlowCollisionSystem::modifySelfCollisionRadius(int jointIndex, float radius) { - int collisionIndex = findSelfCollisionWithJoint(jointIndex); - if (collisionIndex > -1) { - _selfCollisions[collisionIndex]._initialRadius = radius; - //_selfCollisions[collisionIndex]._radius = _scale * radius; - } -}; - -void FlowCollisionSystem::modifySelfCollisionYOffset(int jointIndex, float offset) { - int collisionIndex = findSelfCollisionWithJoint(jointIndex); - if (collisionIndex > -1) { - auto currentOffset = _selfCollisions[collisionIndex]._offset; - _selfCollisions[collisionIndex]._initialOffset = glm::vec3(currentOffset.x, offset, currentOffset.z); - //_selfCollisions[collisionIndex]._offset = _selfCollisions[collisionIndex]._initialOffset * _scale; - } -}; - -void FlowCollisionSystem::modifySelfCollisionOffset(int jointIndex, const glm::vec3& offset) { - int collisionIndex = findSelfCollisionWithJoint(jointIndex); - if (collisionIndex > -1) { - _selfCollisions[collisionIndex]._initialOffset = offset; - //_selfCollisions[collisionIndex]._offset = _selfCollisions[collisionIndex]._initialOffset * _scale; - } -}; FlowCollisionSettings FlowCollisionSystem::getCollisionSettingsByJoint(int jointIndex) { for (auto &collision : _selfCollisions) { if (collision._jointIndex == jointIndex) { @@ -243,13 +209,11 @@ void FlowNode::update(float deltaTime, const glm::vec3& accelerationOffset) { // Add offset _acceleration += accelerationOffset; - - //glm::vec3 deltaAcceleration = timeRatio * _acceleration * glm::pow(_settings._delta * _scale, 2); - glm::vec3 deltaAcceleration = timeRatio * _acceleration * glm::pow(_settings._delta, 2); + float accelerationFactor = glm::pow(_settings._delta, 2) * timeRatio; + glm::vec3 deltaAcceleration = _acceleration * accelerationFactor; // Calculate new position - _currentPosition = (_currentPosition + _currentVelocity * _settings._damping) + deltaAcceleration; - } - else { + _currentPosition = _currentPosition + (_currentVelocity * _settings._damping) + deltaAcceleration; + } else { _acceleration = glm::vec3(0.0f); _currentVelocity = glm::vec3(0.0f); } @@ -273,8 +237,7 @@ void FlowNode::solveCollisions(const FlowCollisionResult& collision) { if (_colliding) { _currentPosition = _currentPosition + collision._normal * collision._offset; _previousCollision = collision; - } - else { + } else { _previousCollision = FlowCollisionResult(); } }; @@ -317,7 +280,8 @@ void FlowJoint::update(float deltaTime) { glm::vec3 accelerationOffset = glm::vec3(0.0f); if (_node._settings._stiffness > 0.0f) { glm::vec3 recoveryVector = _recoveryPosition - _node._currentPosition; - accelerationOffset = recoveryVector * glm::pow(_node._settings._stiffness, 3); + float recoveryFactor = glm::pow(_node._settings._stiffness, 3); + accelerationOffset = recoveryVector * recoveryFactor; } _node.update(deltaTime, accelerationOffset); if (_node._anchored) { @@ -386,7 +350,8 @@ void FlowThread::computeRecovery() { glm::quat parentRotation = parentJoint._parentWorldRotation * parentJoint._initialRotation; for (size_t i = 1; i < _joints.size(); i++) { auto joint = _jointsPointer->at(_joints[i]); - glm::quat rotation = i == 1 ? parentRotation : rotation * parentJoint._initialRotation; + glm::quat rotation; + rotation = (i == 1) ? parentRotation : parentJoint._initialRotation; _jointsPointer->at(_joints[i])._recoveryPosition = joint._recoveryPosition = parentJoint._recoveryPosition + (rotation * (joint._initialTranslation * 0.01f)); parentJoint = joint; } @@ -395,8 +360,11 @@ void FlowThread::computeRecovery() { void FlowThread::update(float deltaTime) { if (getActive()) { _positions.clear(); - _radius = _jointsPointer->at(_joints[0])._node._settings._radius; - computeRecovery(); + auto &firstJoint = _jointsPointer->at(_joints[0]); + _radius = firstJoint._node._settings._radius; + if (firstJoint._node._settings._stiffness > 0.0f) { + computeRecovery(); + } for (size_t i = 0; i < _joints.size(); i++) { auto &joint = _jointsPointer->at(_joints[i]); joint.update(deltaTime); @@ -405,11 +373,10 @@ void FlowThread::update(float deltaTime) { } }; -void FlowThread::solve(bool useCollisions, FlowCollisionSystem& collisionSystem) { +void FlowThread::solve(FlowCollisionSystem& collisionSystem) { if (getActive()) { - if (useCollisions) { + if (collisionSystem.getActive()) { auto bodyCollisions = collisionSystem.checkFlowThreadCollisions(this); - int handTouchedJoint = -1; for (size_t i = 0; i < _joints.size(); i++) { int index = _joints[i]; _jointsPointer->at(index).solve(bodyCollisions[i]); @@ -471,10 +438,15 @@ bool FlowThread::getActive() { return _jointsPointer->at(_joints[0])._node._active; }; -void Flow::init() { - if (!_initialized) { - calculateConstraints(); +void Flow::init(bool isActive, bool isCollidable) { + if (isActive) { + if (!_initialized) { + calculateConstraints(); + } + } else { + cleanUp(); } + } void Flow::calculateConstraints() { @@ -509,18 +481,18 @@ void Flow::calculateConstraints() { if (isFlowJoint || isSimJoint) { group = ""; if (isSimJoint) { - qDebug() << "FLOW is sim: " << name; - for (size_t j = 1; j < name.size() - 1; j++) { + for (int j = 1; j < name.size() - 1; j++) { bool toFloatSuccess; - auto subname = (QStringRef(&name, (int)(name.size() - j), 1)).toString().toFloat(&toFloatSuccess); - if (!toFloatSuccess && (name.size() - j) > simPrefix.size()) { - group = QStringRef(&name, simPrefix.size(), (int)(name.size() - j + 1)).toString(); + QStringRef(&name, (int)(name.size() - j), 1).toString().toFloat(&toFloatSuccess); + if (!toFloatSuccess && (name.size() - j) > (int)simPrefix.size()) { + group = QStringRef(&name, (int)simPrefix.size(), (int)(name.size() - j + 1)).toString(); break; } } if (group.isEmpty()) { - group = QStringRef(&name, simPrefix.size(), name.size() - 1).toString(); + group = QStringRef(&name, (int)simPrefix.size(), name.size() - 1).toString(); } + qCDebug(animation) << "Sim joint added to flow: " << name; } else { group = split[1]; } @@ -559,12 +531,12 @@ void Flow::calculateConstraints() { std::vector roots; - for (auto& itr = _flowJointData.begin(); itr != _flowJointData.end(); itr++) { - if (_flowJointData.find(itr->second._parentIndex) == _flowJointData.end()) { - itr->second._node._anchored = true; - roots.push_back(itr->first); + for (auto &joint :_flowJointData) { + if (_flowJointData.find(joint.second._parentIndex) == _flowJointData.end()) { + joint.second._node._anchored = true; + roots.push_back(joint.first); } else { - _flowJointData[itr->second._parentIndex]._childIndex = itr->first; + _flowJointData[joint.second._parentIndex]._childIndex = joint.first; } } @@ -629,6 +601,10 @@ void Flow::cleanUp() { _initialized = false; _isScaleSet = false; _active = false; + if (_rig) { + _rig->clearJointStates(); + } + } void Flow::setTransform(float scale, const glm::vec3& position, const glm::quat& rotation) { @@ -638,52 +614,49 @@ void Flow::setTransform(float scale, const glm::vec3& position, const glm::quat& _active = _initialized; } +void Flow::setScale(float scale) { + if (!_isScaleSet) { + for (auto &joint : _flowJointData) { + joint.second._initialLength = joint.second._length / _scale; + } + _isScaleSet = true; + } + _lastScale = _scale; + _collisionSystem.setScale(_scale); + for (size_t i = 0; i < _jointThreads.size(); i++) { + for (size_t j = 0; j < _jointThreads[i]._joints.size(); j++) { + auto &joint = _flowJointData[_jointThreads[i]._joints[j]]; + joint._node._settings._radius = joint._node._initialRadius * _scale; + joint._length = joint._initialLength * _scale; + } + _jointThreads[i].resetLength(); + } +} + void Flow::update(float deltaTime) { if (_initialized && _active) { - QElapsedTimer _timer; - _timer.start(); + uint64_t startTime = usecTimestampNow(); + uint64_t updateExpiry = startTime + MAX_UPDATE_FLOW_TIME_BUDGET; if (_scale != _lastScale) { - if (!_isScaleSet) { - for (auto &joint: _flowJointData) { - joint.second._initialLength = joint.second._length / _scale; - } - _isScaleSet = true; - } - _lastScale = _scale; - _collisionSystem.setScale(_scale); - for (int i = 0; i < _jointThreads.size(); i++) { - for (int j = 0; j < _jointThreads[i]._joints.size(); j++) { - auto &joint = _flowJointData[_jointThreads[i]._joints[j]]; - joint._node._settings._radius = joint._node._initialRadius * _scale; - joint._length = joint._initialLength * _scale; - } - _jointThreads[i].resetLength(); - } + setScale(_scale); } updateJoints(); for (size_t i = 0; i < _jointThreads.size(); i++) { size_t index = _invertThreadLoop ? _jointThreads.size() - 1 - i : i; auto &thread = _jointThreads[index]; thread.update(deltaTime); - thread.solve(USE_COLLISIONS, _collisionSystem); + thread.solve(_collisionSystem); if (!updateRootFramePositions(index)) { return; } thread.apply(); - if (_timer.elapsed() > MAX_UPDATE_FLOW_TIME_BUDGET) { + if (usecTimestampNow() > updateExpiry) { break; qWarning(animation) << "Flow Bones ran out of time updating threads"; } } setJoints(); _invertThreadLoop = !_invertThreadLoop; - _deltaTime += _timer.nsecsElapsed(); - _updates++; - if (_deltaTime > _deltaTimeLimit) { - qDebug() << "Flow C++ update " << _deltaTime / _updates << " nanoSeconds "; - _deltaTime = 0; - _updates = 0; - } } } @@ -753,15 +726,6 @@ void Flow::setOthersCollision(const QUuid& otherId, int jointIndex, const glm::v _collisionSystem.addCollisionSphere(jointIndex, settings, position, false, true); } -FlowPhysicsSettings Flow::getPhysicsSettingsForGroup(const QString& group) { - for (auto &joint : _flowJointData) { - if (joint.second._group.toUpper() == group.toUpper()) { - return joint.second._node._settings; - } - } - return FlowPhysicsSettings(); -} - void Flow::setPhysicsSettingsForGroup(const QString& group, const FlowPhysicsSettings& settings) { for (auto &joint : _flowJointData) { if (joint.second._group.toUpper() == group.toUpper()) { diff --git a/libraries/animation/src/Flow.h b/libraries/animation/src/Flow.h index 7f77df0beb..bb15846b5e 100644 --- a/libraries/animation/src/Flow.h +++ b/libraries/animation/src/Flow.h @@ -11,7 +11,6 @@ #ifndef hifi_Flow_h #define hifi_Flow_h -#include #include #include #include @@ -22,11 +21,7 @@ class Rig; class AnimSkeleton; -const bool SHOW_AVATAR = true; -const bool SHOW_DEBUG_SHAPES = false; -const bool SHOW_SOLID_SHAPES = false; const bool SHOW_DUMMY_JOINTS = false; -const bool USE_COLLISIONS = true; const int LEFT_HAND = 0; const int RIGHT_HAND = 1; @@ -55,7 +50,7 @@ const float DUMMY_JOINT_DISTANCE = 0.05f; const float ISOLATED_JOINT_STIFFNESS = 0.0f; const float ISOLATED_JOINT_LENGTH = 0.05f; -const float DEFAULT_STIFFNESS = 0.8f; +const float DEFAULT_STIFFNESS = 0.0f; const float DEFAULT_GRAVITY = -0.0096f; const float DEFAULT_DAMPING = 0.85f; const float DEFAULT_INERTIA = 0.8f; @@ -76,7 +71,7 @@ struct FlowPhysicsSettings { _radius = radius; } bool _active{ true }; - float _stiffness{ 0.0f }; + float _stiffness{ DEFAULT_STIFFNESS }; float _gravity{ DEFAULT_GRAVITY }; float _damping{ DEFAULT_DAMPING }; float _inertia{ DEFAULT_INERTIA }; @@ -158,11 +153,6 @@ public: std::vector checkFlowThreadCollisions(FlowThread* flowThread); - int findSelfCollisionWithJoint(int jointIndex); - void modifySelfCollisionRadius(int jointIndex, float radius); - void modifySelfCollisionYOffset(int jointIndex, float offset); - void modifySelfCollisionOffset(int jointIndex, const glm::vec3& offset); - std::vector& getSelfCollisions() { return _selfCollisions; }; void setOthersCollisions(const std::vector& othersCollisions) { _othersCollisions = othersCollisions; } void prepareCollisions(); @@ -171,11 +161,14 @@ public: void setScale(float scale); FlowCollisionSettings getCollisionSettingsByJoint(int jointIndex); void setCollisionSettingsByJoint(int jointIndex, const FlowCollisionSettings& settings); + void setActive(bool active) { _active = active; } + bool getActive() const { return _active; } protected: std::vector _selfCollisions; std::vector _othersCollisions; std::vector _allCollisions; - float _scale{ 1.0f }; + float _scale { 1.0f }; + bool _active { false }; }; class FlowNode { @@ -260,7 +253,7 @@ public: void computeFlowThread(int rootIndex); void computeRecovery(); void update(float deltaTime); - void solve(bool useCollisions, FlowCollisionSystem& collisionSystem); + void solve(FlowCollisionSystem& collisionSystem); void computeJointRotations(); void apply(); bool getActive(); @@ -277,7 +270,7 @@ public: class Flow { public: Flow(Rig* rig) { _rig = rig; }; - void init(); + void init(bool isActive, bool isCollidable); bool isActive() { return _active; } void calculateConstraints(); void update(float deltaTime); @@ -286,7 +279,6 @@ public: const std::vector& getThreads() const { return _jointThreads; } void setOthersCollision(const QUuid& otherId, int jointIndex, const glm::vec3& position); FlowCollisionSystem& getCollisionSystem() { return _collisionSystem; } - FlowPhysicsSettings getPhysicsSettingsForGroup(const QString& group); void setPhysicsSettingsForGroup(const QString& group, const FlowPhysicsSettings& settings); private: void setJoints(); @@ -294,6 +286,7 @@ private: void updateJoints(); bool updateRootFramePositions(size_t threadIndex); bool worldToJointPoint(const glm::vec3& position, const int jointIndex, glm::vec3& jointSpacePosition) const; + void setScale(float scale); Rig* _rig; float _scale { 1.0f }; float _lastScale{ 1.0f }; @@ -306,9 +299,6 @@ private: bool _initialized { false }; bool _active { false }; bool _isScaleSet { false }; - int _deltaTime { 0 }; - int _deltaTimeLimit { 4000000 }; - int _updates { 0 }; bool _invertThreadLoop { false }; }; From c966f71cb1e040bde1a87a439dabb96c7e9e5cd9 Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Fri, 15 Feb 2019 10:17:37 -0700 Subject: [PATCH 077/112] More fixes --- interface/src/avatar/MyAvatar.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 96fdd6a9e1..f2e69ab5d3 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -5331,7 +5331,7 @@ void MyAvatar::useFlow(bool isActive, bool isCollidable, const QVariantMap& phys auto physicsGroups = physicsConfig.keys(); if (physicsGroups.size() > 0) { for (auto &groupName : physicsGroups) { - auto &settings = physicsConfig[groupName].toMap(); + auto settings = physicsConfig[groupName].toMap(); FlowPhysicsSettings physicsSettings; if (settings.contains("active")) { physicsSettings._active = settings["active"].toBool(); @@ -5363,7 +5363,7 @@ void MyAvatar::useFlow(bool isActive, bool isCollidable, const QVariantMap& phys for (auto &jointName : collisionJoints) { int jointIndex = getJointIndex(jointName); FlowCollisionSettings collisionsSettings; - auto &settings = collisionsConfig[jointName].toMap(); + auto settings = collisionsConfig[jointName].toMap(); collisionsSettings._entityID = getID(); if (settings.contains("radius")) { collisionsSettings._radius = settings["radius"].toFloat(); From d6dfaacf6fd4eca7b4e71c84757c80aa8eae2a42 Mon Sep 17 00:00:00 2001 From: amantley Date: Fri, 15 Feb 2019 10:35:25 -0800 Subject: [PATCH 078/112] adding ifdef for android os --- interface/src/avatar/MyAvatar.cpp | 3 +++ libraries/animation/src/AnimSplineIK.cpp | 8 ++++---- libraries/animation/src/Rig.cpp | 11 ++++++++--- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index b5a938faba..aa47c63572 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -2951,6 +2951,9 @@ void MyAvatar::initAnimGraph() { graphUrl = _fstAnimGraphOverrideUrl; } else { graphUrl = PathUtils::resourcesUrl("avatar/avatar-animation.json"); + #ifdef Q_OS_ANDROID + graphUrl = PathUtils::resourcesUrl("avatar/avatar-animation_withSplineIKNode.json"); + #endif } emit animGraphUrlChanged(graphUrl); diff --git a/libraries/animation/src/AnimSplineIK.cpp b/libraries/animation/src/AnimSplineIK.cpp index 72dcbfc5e7..c91bd3bae2 100644 --- a/libraries/animation/src/AnimSplineIK.cpp +++ b/libraries/animation/src/AnimSplineIK.cpp @@ -131,7 +131,7 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const baseParentAbsPose = _skeleton->getAbsolutePose(baseParentIndex, _poses); } _poses[_baseJointIndex] = baseParentAbsPose.inverse() * baseTargetAbsolutePose; - _poses[_baseJointIndex].scale() = glm::vec3(1.0f); + _poses[_baseJointIndex].scale() = 1.0f; // initialize the middle joint target IKTarget midTarget; @@ -290,7 +290,7 @@ void AnimSplineIK::setSkeletonInternal(AnimSkeleton::ConstPointer skeleton) { void AnimSplineIK::solveTargetWithSpline(const AnimContext& context, int base, const IKTarget& target, const AnimPoseVec& absolutePoses, bool debug, AnimChain& chainInfoOut) const { // build spline from tip to base - AnimPose tipPose = AnimPose(glm::vec3(1.0f), target.getRotation(), target.getTranslation()); + AnimPose tipPose = AnimPose(1.0f, target.getRotation(), target.getTranslation()); AnimPose basePose = absolutePoses[base]; CubicHermiteSplineFunctorWithArcLength spline; @@ -338,7 +338,7 @@ void AnimSplineIK::solveTargetWithSpline(const AnimContext& context, int base, c glm::mat3 m(u, v, glm::cross(u, v)); glm::quat rot = glm::normalize(glm::quat_cast(m)); - AnimPose desiredAbsPose = AnimPose(glm::vec3(1.0f), rot, trans) * splineJointInfo.offsetPose; + AnimPose desiredAbsPose = AnimPose(1.0f, rot, trans) * splineJointInfo.offsetPose; // apply flex coefficent AnimPose flexedAbsPose; @@ -457,7 +457,7 @@ void AnimSplineIK::computeAndCacheSplineJointInfosForIKTarget(const AnimContext& glm::mat3 m(u, v, glm::cross(u, v)); glm::quat rot = glm::normalize(glm::quat_cast(m)); - AnimPose pose(glm::vec3(1.0f), rot, spline(t)); + AnimPose pose(1.0f, rot, spline(t)); AnimPose offsetPose = pose.inverse() * defaultPose; SplineJointInfo splineJointInfo = { index, ratio, offsetPose }; diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index d25ea4669c..e3b997e8cc 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -1516,8 +1516,13 @@ void Rig::updateHands(bool leftHandEnabled, bool rightHandEnabled, bool hipsEnab if (ENABLE_POLE_VECTORS && handJointIndex >= 0 && armJointIndex >= 0 && elbowJointIndex >= 0 && oppositeArmJointIndex >= 0) { glm::vec3 poleVector; - //bool usePoleVector = calculateElbowPoleVector(handJointIndex, elbowJointIndex, armJointIndex, oppositeArmJointIndex, poleVector); - bool usePoleVector = calculateElbowPoleVectorOptimized(handJointIndex, elbowJointIndex, armJointIndex, false, poleVector); + bool usePoleVector = false; + #ifdef Q_OS_ANDROID + usePoleVector = calculateElbowPoleVectorOptimized(handJointIndex, elbowJointIndex, armJointIndex, false, poleVector); + #else + usePoleVector = calculateElbowPoleVectorOptimized(handJointIndex, elbowJointIndex, armJointIndex, false, poleVector); + // bool usePoleVector = calculateElbowPoleVector(handJointIndex, elbowJointIndex, armJointIndex, oppositeArmJointIndex, poleVector); + #endif if (usePoleVector) { glm::vec3 sensorPoleVector = transformVectorFast(rigToSensorMatrix, poleVector); _animVars.set("rightHandPoleVectorEnabled", true); @@ -1708,7 +1713,7 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s // calculate the reference axis and the side axis. // Look up refVector from animVars, make sure to convert into geom space. - glm::vec3 refVector = (AnimPose(_rigToGeometryTransform) * elbowPose).xformVectorFast(Vectors::UNIT_X); + glm::vec3 refVector = (AnimPose(_rigToGeometryTransform) * elbowPose).xformVector(Vectors::UNIT_X); float refVectorLength = glm::length(refVector); if (left) { From 7119bc597243c4e7e881d65fb627f16c51103600 Mon Sep 17 00:00:00 2001 From: amantley Date: Fri, 15 Feb 2019 10:54:02 -0800 Subject: [PATCH 079/112] reverted the scale optimization in animspline.cpp --- libraries/animation/src/AnimSplineIK.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libraries/animation/src/AnimSplineIK.cpp b/libraries/animation/src/AnimSplineIK.cpp index c91bd3bae2..72dcbfc5e7 100644 --- a/libraries/animation/src/AnimSplineIK.cpp +++ b/libraries/animation/src/AnimSplineIK.cpp @@ -131,7 +131,7 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const baseParentAbsPose = _skeleton->getAbsolutePose(baseParentIndex, _poses); } _poses[_baseJointIndex] = baseParentAbsPose.inverse() * baseTargetAbsolutePose; - _poses[_baseJointIndex].scale() = 1.0f; + _poses[_baseJointIndex].scale() = glm::vec3(1.0f); // initialize the middle joint target IKTarget midTarget; @@ -290,7 +290,7 @@ void AnimSplineIK::setSkeletonInternal(AnimSkeleton::ConstPointer skeleton) { void AnimSplineIK::solveTargetWithSpline(const AnimContext& context, int base, const IKTarget& target, const AnimPoseVec& absolutePoses, bool debug, AnimChain& chainInfoOut) const { // build spline from tip to base - AnimPose tipPose = AnimPose(1.0f, target.getRotation(), target.getTranslation()); + AnimPose tipPose = AnimPose(glm::vec3(1.0f), target.getRotation(), target.getTranslation()); AnimPose basePose = absolutePoses[base]; CubicHermiteSplineFunctorWithArcLength spline; @@ -338,7 +338,7 @@ void AnimSplineIK::solveTargetWithSpline(const AnimContext& context, int base, c glm::mat3 m(u, v, glm::cross(u, v)); glm::quat rot = glm::normalize(glm::quat_cast(m)); - AnimPose desiredAbsPose = AnimPose(1.0f, rot, trans) * splineJointInfo.offsetPose; + AnimPose desiredAbsPose = AnimPose(glm::vec3(1.0f), rot, trans) * splineJointInfo.offsetPose; // apply flex coefficent AnimPose flexedAbsPose; @@ -457,7 +457,7 @@ void AnimSplineIK::computeAndCacheSplineJointInfosForIKTarget(const AnimContext& glm::mat3 m(u, v, glm::cross(u, v)); glm::quat rot = glm::normalize(glm::quat_cast(m)); - AnimPose pose(1.0f, rot, spline(t)); + AnimPose pose(glm::vec3(1.0f), rot, spline(t)); AnimPose offsetPose = pose.inverse() * defaultPose; SplineJointInfo splineJointInfo = { index, ratio, offsetPose }; From b670f72e8422f966d58a684831e93c30cfbf2063 Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Fri, 15 Feb 2019 12:35:17 -0700 Subject: [PATCH 080/112] fix warning on linux --- libraries/animation/src/Flow.cpp | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/libraries/animation/src/Flow.cpp b/libraries/animation/src/Flow.cpp index 607b2775e0..974dd8dc54 100644 --- a/libraries/animation/src/Flow.cpp +++ b/libraries/animation/src/Flow.cpp @@ -46,7 +46,7 @@ FlowCollisionResult FlowCollisionSphere::checkSegmentCollision(const glm::vec3& FlowCollisionResult result; auto segment = point2 - point1; auto segmentLength = glm::length(segment); - auto maxDistance = glm::sqrt(glm::pow(collisionResult1._radius, 2) + glm::pow(segmentLength, 2)); + auto maxDistance = glm::sqrt(powf(collisionResult1._radius, 2.0f) + powf(segmentLength, 2.0f)); if (collisionResult1._distance < maxDistance && collisionResult2._distance < maxDistance) { float segmentPercentage = collisionResult1._distance / (collisionResult1._distance + collisionResult2._distance); glm::vec3 collisionPoint = point1 + segment * segmentPercentage; @@ -123,21 +123,17 @@ std::vector FlowCollisionSystem::checkFlowThreadCollisions( auto prevCollision = collisionData[i - 1]; nextCollision = _allCollisions[j].computeSphereCollision(flowThread->_positions[i], flowThread->_radius); collisionData.push_back(nextCollision); - bool isTouching = false; if (prevCollision._offset > 0.0f) { if (i == 1) { FlowThreadResults[i - 1].push_back(prevCollision); - isTouching = true; } } else if (nextCollision._offset > 0.0f) { FlowThreadResults[i].push_back(nextCollision); - isTouching = true; } else { FlowCollisionResult segmentCollision = _allCollisions[j].checkSegmentCollision(flowThread->_positions[i - 1], flowThread->_positions[i], prevCollision, nextCollision); if (segmentCollision._offset > 0) { FlowThreadResults[i - 1].push_back(segmentCollision); FlowThreadResults[i].push_back(segmentCollision); - isTouching = true; } } } @@ -209,7 +205,7 @@ void FlowNode::update(float deltaTime, const glm::vec3& accelerationOffset) { // Add offset _acceleration += accelerationOffset; - float accelerationFactor = glm::pow(_settings._delta, 2) * timeRatio; + float accelerationFactor = powf(_settings._delta, 2.0f) * timeRatio; glm::vec3 deltaAcceleration = _acceleration * accelerationFactor; // Calculate new position _currentPosition = _currentPosition + (_currentVelocity * _settings._damping) + deltaAcceleration; @@ -280,7 +276,7 @@ void FlowJoint::update(float deltaTime) { glm::vec3 accelerationOffset = glm::vec3(0.0f); if (_node._settings._stiffness > 0.0f) { glm::vec3 recoveryVector = _recoveryPosition - _node._currentPosition; - float recoveryFactor = glm::pow(_node._settings._stiffness, 3); + float recoveryFactor = powf(_node._settings._stiffness, 3.0f); accelerationOffset = recoveryVector * recoveryFactor; } _node.update(deltaTime, accelerationOffset); From 3f9b761e426a10cf1b28eef497d1cf1f62fb1f5a Mon Sep 17 00:00:00 2001 From: amantley Date: Fri, 15 Feb 2019 14:05:42 -0800 Subject: [PATCH 081/112] updating the android only if defs --- .../src/AnimPoleVectorConstraint.cpp | 52 +++++++---- libraries/animation/src/Rig.cpp | 88 ++++++------------- libraries/animation/src/Rig.h | 2 +- 3 files changed, 63 insertions(+), 79 deletions(-) diff --git a/libraries/animation/src/AnimPoleVectorConstraint.cpp b/libraries/animation/src/AnimPoleVectorConstraint.cpp index d575ddabe4..67fbefdf6f 100644 --- a/libraries/animation/src/AnimPoleVectorConstraint.cpp +++ b/libraries/animation/src/AnimPoleVectorConstraint.cpp @@ -58,10 +58,6 @@ const AnimPoseVec& AnimPoleVectorConstraint::evaluate(const AnimVariantMap& anim // Look up poleVector from animVars, make sure to convert into geom space. glm::vec3 poleVector = animVars.lookupRigToGeometryVector(_poleVectorVar, Vectors::UNIT_Z); - if (_skeleton->nameToJointIndex("LeftHand") == _tipJointIndex) { - //float thetaFromRig = animVars.lookup("thetaRight", 0.0f); - //qCDebug(animation) << " anim pole vector theta from rig " << thetaFromRig; - } // determine if we should interpolate bool enabled = animVars.lookup(_enabledVar, _enabled); @@ -116,25 +112,20 @@ const AnimPoseVec& AnimPoleVectorConstraint::evaluate(const AnimVariantMap& anim // project poleVector on plane formed by axis. glm::vec3 poleVectorProj = poleVector - glm::dot(poleVector, unitAxis) * unitAxis; float poleVectorProjLength = glm::length(poleVectorProj); + +#ifdef Q_OS_ANDROID - // double check for zero length vectors or vectors parallel to rotaiton axis. - if (axisLength > MIN_LENGTH && refVectorLength > MIN_LENGTH && sideVectorLength > MIN_LENGTH && - refVectorProjLength > MIN_LENGTH && poleVectorProjLength > MIN_LENGTH) { + // get theta set by optimized ik for Quest + if ((_skeleton->nameToJointIndex("RightHand") == _tipJointIndex) || (_skeleton->nameToJointIndex("LeftHand") == _tipJointIndex)) { - float dot = glm::clamp(glm::dot(refVectorProj / refVectorProjLength, poleVectorProj / poleVectorProjLength), 0.0f, 1.0f); - float sideDot = glm::dot(poleVector, sideVector); - float theta = copysignf(1.0f, sideDot) * acosf(dot); - - // overwrite theta if we are using optimized code - if ((_skeleton->nameToJointIndex("RightHand") == _tipJointIndex) || (_skeleton->nameToJointIndex("LeftHand") == _tipJointIndex)) { - - if (_skeleton->nameToJointIndex("LeftHand") == _tipJointIndex) { - theta = animVars.lookup("thetaLeftElbow", 0.0f); - } else if (_skeleton->nameToJointIndex("RightHand") == _tipJointIndex) { - theta = animVars.lookup("thetaRightElbow", 0.0f); - } + float theta; + if (_skeleton->nameToJointIndex("LeftHand") == _tipJointIndex) { + theta = animVars.lookup("thetaLeftElbow", 0.0f); + } else if (_skeleton->nameToJointIndex("RightHand") == _tipJointIndex) { + theta = animVars.lookup("thetaRightElbow", 0.0f); } + glm::quat deltaRot = glm::angleAxis(theta, unitAxis); // transform result back into parent relative frame. @@ -145,6 +136,29 @@ const AnimPoseVec& AnimPoleVectorConstraint::evaluate(const AnimVariantMap& anim ikChain.setRelativePoseAtJointIndex(_tipJointIndex, AnimPose(relTipRot, underPoses[_tipJointIndex].trans())); } +#else + // double check for zero length vectors or vectors parallel to rotaiton axis. + if (axisLength > MIN_LENGTH && refVectorLength > MIN_LENGTH && sideVectorLength > MIN_LENGTH && + refVectorProjLength > MIN_LENGTH && poleVectorProjLength > MIN_LENGTH) { + + float dot = glm::clamp(glm::dot(refVectorProj / refVectorProjLength, poleVectorProj / poleVectorProjLength), 0.0f, 1.0f); + float sideDot = glm::dot(poleVector, sideVector); + float theta = copysignf(1.0f, sideDot) * acosf(dot); + + + + glm::quat deltaRot = glm::angleAxis(theta, unitAxis); + + // transform result back into parent relative frame. + glm::quat relBaseRot = glm::inverse(baseParentPose.rot()) * deltaRot * basePose.rot(); + ikChain.setRelativePoseAtJointIndex(_baseJointIndex, AnimPose(relBaseRot, underPoses[_baseJointIndex].trans())); + + glm::quat relTipRot = glm::inverse(midPose.rot()) * glm::inverse(deltaRot) * tipPose.rot(); + ikChain.setRelativePoseAtJointIndex(_tipJointIndex, AnimPose(relTipRot, underPoses[_tipJointIndex].trans())); + } + +#endif + // start off by initializing output poses with the underPoses _poses = underPoses; diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index 27ae8858d7..3cef6e677d 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -1459,9 +1459,19 @@ void Rig::updateHands(bool leftHandEnabled, bool rightHandEnabled, bool hipsEnab int elbowJointIndex = _animSkeleton->nameToJointIndex("LeftForeArm"); int oppositeArmJointIndex = _animSkeleton->nameToJointIndex("RightArm"); if (ENABLE_POLE_VECTORS && handJointIndex >= 0 && armJointIndex >= 0 && elbowJointIndex >= 0 && oppositeArmJointIndex >= 0) { + #ifdef Q_OS_ANDROID + float poleTheta; + bool usePoleTheta = calculateElbowPoleVectorOptimized(handJointIndex, elbowJointIndex, armJointIndex, true, poleTheta); + if (usePoleTheta) { + _animVars.set("leftHandPoleVectorEnabled", true); + _animVars.set("leftHandPoleReferenceVector", Vectors::UNIT_X); + _animVars.set("thetaLeftElbow", transformVectorFast(sensorToRigMatrix, sensorPoleVector)); + } else { + _animVars.set("leftHandPoleVectorEnabled", false); + } + #else glm::vec3 poleVector; - //bool usePoleVector = calculateElbowPoleVector(handJointIndex, elbowJointIndex, armJointIndex, oppositeArmJointIndex, poleVector); - bool usePoleVector = calculateElbowPoleVectorOptimized(handJointIndex, elbowJointIndex, armJointIndex, true, poleVector); + bool usePoleVector = calculateElbowPoleVector(handJointIndex, elbowJointIndex, armJointIndex, oppositeArmJointIndex, poleVector); if (usePoleVector) { glm::vec3 sensorPoleVector = transformVectorFast(rigToSensorMatrix, poleVector); _animVars.set("leftHandPoleVectorEnabled", true); @@ -1470,6 +1480,8 @@ void Rig::updateHands(bool leftHandEnabled, bool rightHandEnabled, bool hipsEnab } else { _animVars.set("leftHandPoleVectorEnabled", false); } + #endif + } else { _animVars.set("leftHandPoleVectorEnabled", false); } @@ -1515,14 +1527,19 @@ void Rig::updateHands(bool leftHandEnabled, bool rightHandEnabled, bool hipsEnab int oppositeArmJointIndex = _animSkeleton->nameToJointIndex("LeftArm"); if (ENABLE_POLE_VECTORS && handJointIndex >= 0 && armJointIndex >= 0 && elbowJointIndex >= 0 && oppositeArmJointIndex >= 0) { - glm::vec3 poleVector; - bool usePoleVector = false; #ifdef Q_OS_ANDROID - usePoleVector = calculateElbowPoleVectorOptimized(handJointIndex, elbowJointIndex, armJointIndex, false, poleVector); + float poleTheta; + bool usePoleTheta = calculateElbowPoleVectorOptimized(handJointIndex, elbowJointIndex, armJointIndex, true, poleTheta); + if (usePoleTheta) { + _animVars.set("rightHandPoleVectorEnabled", true); + _animVars.set("rightHandPoleReferenceVector", Vectors::UNIT_X); + _animVars.set("thetaRightElbow", poleTheta); + } else { + _animVars.set("rightHandPoleVectorEnabled", false); + } #else - usePoleVector = calculateElbowPoleVectorOptimized(handJointIndex, elbowJointIndex, armJointIndex, false, poleVector); - // bool usePoleVector = calculateElbowPoleVector(handJointIndex, elbowJointIndex, armJointIndex, oppositeArmJointIndex, poleVector); - #endif + glm::vec3 poleVector; + bool usePoleVector = calculateElbowPoleVector(handJointIndex, elbowJointIndex, armJointIndex, oppositeArmJointIndex, poleVector); if (usePoleVector) { glm::vec3 sensorPoleVector = transformVectorFast(rigToSensorMatrix, poleVector); _animVars.set("rightHandPoleVectorEnabled", true); @@ -1531,6 +1548,8 @@ void Rig::updateHands(bool leftHandEnabled, bool rightHandEnabled, bool hipsEnab } else { _animVars.set("rightHandPoleVectorEnabled", false); } + + #endif } else { _animVars.set("rightHandPoleVectorEnabled", false); } @@ -1688,7 +1707,7 @@ void Rig::updateEyeJoint(int index, const glm::vec3& modelTranslation, const glm } } -bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int shoulderIndex, bool left, glm::vec3& poleVector) { +bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int shoulderIndex, bool left, float& poleTheta) { // get the default poses for the upper and lower arm // then use this length to judge how far the hand is away from the shoulder. // then create weights that make the elbow angle less when the x value is large in either direction. @@ -1711,36 +1730,7 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s AnimPose absoluteHandPose = getAbsoluteDefaultPose(handIndex); float defaultArmLength = glm::length(absoluteHandPose.trans() - absoluteShoulderPose.trans()); - // calculate the reference axis and the side axis. - // Look up refVector from animVars, make sure to convert into geom space. - glm::vec3 refVector = (AnimPose(_rigToGeometryTransform) * elbowPose).xformVector(Vectors::UNIT_X); - float refVectorLength = glm::length(refVector); - - if (left) { - //AnimPose temp(_rigToGeometryTransform); - //glm::mat4 elbowMat(elbowPose); - //AnimPose result3(_rigToGeometryTransform * elbowMat); - //AnimPose geomElbow2 = temp * elbowPose; - //qCDebug(animation) << "mid pose geom2 rig" << geomElbow2; - //qCDebug(animation) << "mid pose result rig" << result3; - //qCDebug(animation) << "ref vector rig" << refVector; - } - - AnimPose geomShoulder = AnimPose(_rigToGeometryTransform) * shoulderPose; - AnimPose geomHand = AnimPose(_rigToGeometryTransform) * handPose; - glm::vec3 axis = geomShoulder.trans() - geomHand.trans(); - float axisLength = glm::length(axis); - glm::vec3 unitAxis = axis / axisLength; - - glm::vec3 sideVector = glm::cross(unitAxis, refVector); - float sideVectorLength = glm::length(sideVector); - - // project refVector onto axis plane - glm::vec3 refVectorProj = refVector - glm::dot(refVector, unitAxis) * unitAxis; - float refVectorProjLength = glm::length(refVectorProj); - - // phi_0 is the lowest angle we can have - const float phi_0 = 15.0f; + //calculate the hand position influence on theta const float zStart = 0.6f; const float xStart = 0.1f; // biases @@ -2014,27 +2004,7 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s _animVars.set("thetaRightElbow", thetaRadians); } - // remove this if inaccurate - // convert theta back to pole vector - float lastDot = cosf(((180.0f - theta) / 180.0f)*PI); - float lastSideDot = sqrt(1.0f - (lastDot*lastDot)); - - const float MIN_LENGTH = 1.0e-4f; - if (refVectorLength > MIN_LENGTH && sideVectorLength > MIN_LENGTH) { - poleVector = lastDot * (refVectorProj / refVectorProjLength) + glm::sign(theta) * lastSideDot * (sideVector / sideVectorLength); - if (left) { - //qCDebug(animation) << "pole vector in rig " << poleVector; - } - // - } else { - poleVector = glm::vec3(1.0f, 0.0f, 0.0f); - return false; - } - - return true; - - } bool Rig::calculateElbowPoleVector(int handIndex, int elbowIndex, int armIndex, int oppositeArmIndex, glm::vec3& poleVector) const { diff --git a/libraries/animation/src/Rig.h b/libraries/animation/src/Rig.h index 693aa732fa..4dce28f7ae 100644 --- a/libraries/animation/src/Rig.h +++ b/libraries/animation/src/Rig.h @@ -258,7 +258,7 @@ protected: void calcAnimAlpha(float speed, const std::vector& referenceSpeeds, float* alphaOut) const; bool calculateElbowPoleVector(int handIndex, int elbowIndex, int armIndex, int oppositeArmIndex, glm::vec3& poleVector) const; - bool calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int shoulderIndex, bool left, glm::vec3& poleVector); + bool calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int shoulderIndex, bool left, float& poleTheta); glm::vec3 calculateKneePoleVector(int footJointIndex, int kneeJoint, int upLegIndex, int hipsIndex, const AnimPose& targetFootPose) const; glm::vec3 deflectHandFromTorso(const glm::vec3& handPosition, const HFMJointShapeInfo& hipsShapeInfo, const HFMJointShapeInfo& spineShapeInfo, const HFMJointShapeInfo& spine1ShapeInfo, const HFMJointShapeInfo& spine2ShapeInfo) const; From 36093926d06cdce3da7ea5dc774a700d08353186 Mon Sep 17 00:00:00 2001 From: amantley Date: Fri, 15 Feb 2019 15:00:39 -0800 Subject: [PATCH 082/112] added fake android defines for running the new ik on pc --- interface/src/avatar/MyAvatar.cpp | 3 +++ .../src/AnimPoleVectorConstraint.cpp | 4 +++- libraries/animation/src/Rig.cpp | 19 +++++++++------ tools/unity-avatar-exporter/Assets/README.txt | 23 +++++++++++++++++++ 4 files changed, 41 insertions(+), 8 deletions(-) create mode 100644 tools/unity-avatar-exporter/Assets/README.txt diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 817c870244..ea5f2163fe 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -2943,6 +2943,8 @@ void MyAvatar::setAnimGraphUrl(const QUrl& url) { connect(&(_skeletonModel->getRig()), SIGNAL(onLoadComplete()), this, SLOT(animGraphLoaded())); } +#define FAKE_Q_OS_ANDROID + void MyAvatar::initAnimGraph() { QUrl graphUrl; if (!_prefOverrideAnimGraphUrl.get().isEmpty()) { @@ -2951,6 +2953,7 @@ void MyAvatar::initAnimGraph() { graphUrl = _fstAnimGraphOverrideUrl; } else { graphUrl = PathUtils::resourcesUrl("avatar/avatar-animation.json"); + //#ifdef FAKE_Q_OS_ANDROID #ifdef Q_OS_ANDROID graphUrl = PathUtils::resourcesUrl("avatar/avatar-animation_withSplineIKNode.json"); #endif diff --git a/libraries/animation/src/AnimPoleVectorConstraint.cpp b/libraries/animation/src/AnimPoleVectorConstraint.cpp index 67fbefdf6f..998368a0c6 100644 --- a/libraries/animation/src/AnimPoleVectorConstraint.cpp +++ b/libraries/animation/src/AnimPoleVectorConstraint.cpp @@ -13,6 +13,7 @@ #include "AnimUtil.h" #include "GLMHelpers.h" +#define FAKE_Q_OS_ANDROID true; const float FRAMES_PER_SECOND = 30.0f; const float INTERP_DURATION = 6.0f; @@ -112,7 +113,8 @@ const AnimPoseVec& AnimPoleVectorConstraint::evaluate(const AnimVariantMap& anim // project poleVector on plane formed by axis. glm::vec3 poleVectorProj = poleVector - glm::dot(poleVector, unitAxis) * unitAxis; float poleVectorProjLength = glm::length(poleVectorProj); - + +//#ifdef FAKE_Q_OS_ANDROID #ifdef Q_OS_ANDROID // get theta set by optimized ik for Quest diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index 3cef6e677d..188f2aa790 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -34,6 +34,7 @@ #include "IKTarget.h" #include "PathUtils.h" +#define FAKE_Q_OS_ANDROID true; static int nextRigId = 1; static std::map rigRegistry; @@ -1459,14 +1460,15 @@ void Rig::updateHands(bool leftHandEnabled, bool rightHandEnabled, bool hipsEnab int elbowJointIndex = _animSkeleton->nameToJointIndex("LeftForeArm"); int oppositeArmJointIndex = _animSkeleton->nameToJointIndex("RightArm"); if (ENABLE_POLE_VECTORS && handJointIndex >= 0 && armJointIndex >= 0 && elbowJointIndex >= 0 && oppositeArmJointIndex >= 0) { + //#ifdef FAKE_Q_OS_ANDROID #ifdef Q_OS_ANDROID float poleTheta; bool usePoleTheta = calculateElbowPoleVectorOptimized(handJointIndex, elbowJointIndex, armJointIndex, true, poleTheta); if (usePoleTheta) { _animVars.set("leftHandPoleVectorEnabled", true); _animVars.set("leftHandPoleReferenceVector", Vectors::UNIT_X); - _animVars.set("thetaLeftElbow", transformVectorFast(sensorToRigMatrix, sensorPoleVector)); - } else { + _animVars.set("thetaLeftElbow", poleTheta); + } else { _animVars.set("leftHandPoleVectorEnabled", false); } #else @@ -1527,12 +1529,14 @@ void Rig::updateHands(bool leftHandEnabled, bool rightHandEnabled, bool hipsEnab int oppositeArmJointIndex = _animSkeleton->nameToJointIndex("LeftArm"); if (ENABLE_POLE_VECTORS && handJointIndex >= 0 && armJointIndex >= 0 && elbowJointIndex >= 0 && oppositeArmJointIndex >= 0) { + + //#ifdef FAKE_Q_OS_ANDROID #ifdef Q_OS_ANDROID float poleTheta; - bool usePoleTheta = calculateElbowPoleVectorOptimized(handJointIndex, elbowJointIndex, armJointIndex, true, poleTheta); + bool usePoleTheta = calculateElbowPoleVectorOptimized(handJointIndex, elbowJointIndex, armJointIndex, false, poleTheta); if (usePoleTheta) { _animVars.set("rightHandPoleVectorEnabled", true); - _animVars.set("rightHandPoleReferenceVector", Vectors::UNIT_X); + _animVars.set("rightHandPoleReferenceVector", -Vectors::UNIT_X); _animVars.set("thetaRightElbow", poleTheta); } else { _animVars.set("rightHandPoleVectorEnabled", false); @@ -1951,7 +1955,6 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s // remember direction of travel. const float TWIST_DEADZONE = (4 * PI) / 9.0f; - //if (!isLeft) { float twistCorrection = 0.0f; if (left) { if (fabsf(_twistThetaRunningAverageLeft) > TWIST_DEADZONE) { @@ -1985,7 +1988,8 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s } // convert to radians and make 180 0 to match pole vector theta float thetaRadians = ((180.0f - _lastThetaLeft) / 180.0f)*PI; - _animVars.set("thetaLeftElbow", thetaRadians); + //_animVars.set("thetaLeftElbow", thetaRadians); + poleTheta = thetaRadians; } else { // final global smoothing @@ -2001,7 +2005,8 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s } // convert to radians and make 180 0 to match pole vector theta float thetaRadians = ((180.0f - _lastThetaRight) / 180.0f)*PI; - _animVars.set("thetaRightElbow", thetaRadians); + //_animVars.set("thetaRightElbow", thetaRadians); + poleTheta = thetaRadians; } return true; diff --git a/tools/unity-avatar-exporter/Assets/README.txt b/tools/unity-avatar-exporter/Assets/README.txt new file mode 100644 index 0000000000..f02bc688ae --- /dev/null +++ b/tools/unity-avatar-exporter/Assets/README.txt @@ -0,0 +1,23 @@ +High Fidelity, Inc. +Avatar Exporter +Version 0.1 + +Note: It is recommended to use Unity versions between 2017.4.17f1 and 2018.2.12f1 for this Avatar Exporter. + +To create a new avatar project: +1. Import your .fbx avatar model into your Unity project's Assets by either dragging and dropping the file into the Assets window or by using Assets menu > Import New Assets. +2. Select the .fbx avatar that you imported in step 1 in the Assets window, and in the Rig section of the Inspector window set the Animation Type to Humanoid and choose Apply. +3. With the .fbx avatar still selected in the Assets window, choose High Fidelity menu > Export New Avatar. +4. Select a name for your avatar project (this will be used to create a directory with that name), as well as the target location for your project folder. +5. Once it is exported, your project directory will open in File Explorer. + +To update an existing avatar project: +1. Select the existing .fbx avatar in the Assets window that you would like to re-export. +2. Choose High Fidelity menu > Update Existing Avatar and browse to the .fst file you would like to update. +3. If the .fbx file in your Unity Assets folder is newer than the existing .fbx file in your selected avatar project or vice-versa, you will be prompted if you wish to replace the older file with the newer file before performing the update. +4. Once it is updated, your project directory will open in File Explorer. + +* WARNING * +If you are using any external textures as part of your .fbx model, be sure they are copied into the textures folder that is created in the project folder after exporting a new avatar. + +For further details including troubleshooting tips, see the full documentation at https://docs.highfidelity.com/create-and-explore/avatars/create-avatars/unity-extension From 95530e6ba53096c8412eccb29f9f7eca8e6e4ecc Mon Sep 17 00:00:00 2001 From: amantley Date: Fri, 15 Feb 2019 15:41:23 -0800 Subject: [PATCH 083/112] removed the unnecessary animArmIK.h and .cpp --- libraries/animation/src/AnimArmIK.cpp | 42 -------- libraries/animation/src/AnimArmIK.h | 34 ------ libraries/animation/src/AnimContext.h | 1 - libraries/animation/src/AnimNodeLoader.cpp | 24 ----- libraries/animation/src/Rig.cpp | 114 +++++++++------------ 5 files changed, 50 insertions(+), 165 deletions(-) delete mode 100644 libraries/animation/src/AnimArmIK.cpp delete mode 100644 libraries/animation/src/AnimArmIK.h diff --git a/libraries/animation/src/AnimArmIK.cpp b/libraries/animation/src/AnimArmIK.cpp deleted file mode 100644 index 87606fe5d2..0000000000 --- a/libraries/animation/src/AnimArmIK.cpp +++ /dev/null @@ -1,42 +0,0 @@ -// -// AnimArmIK.cpp -// -// Created by Angus Antley on 1/9/19. -// Copyright (c) 2019 High Fidelity, Inc. All rights reserved. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -#include "AnimArmIK.h" - -#include - -#include "AnimationLogging.h" -#include "AnimUtil.h" - -AnimArmIK::AnimArmIK(const QString& id, float alpha, bool enabled, float interpDuration, - const QString& baseJointName, const QString& midJointName, - const QString& tipJointName, const glm::vec3& midHingeAxis, - const QString& alphaVar, const QString& enabledVar, - const QString& endEffectorRotationVarVar, const QString& endEffectorPositionVarVar) : - AnimTwoBoneIK(id, alpha, enabled, interpDuration, baseJointName, midJointName, tipJointName, midHingeAxis, alphaVar, enabledVar, endEffectorRotationVarVar, endEffectorPositionVarVar) -{ - -} - -AnimArmIK::~AnimArmIK() { - -} - -const AnimPoseVec& AnimArmIK::evaluate(const AnimVariantMap& animVars, const AnimContext& context, float dt, AnimVariantMap& triggersOut) { - - //qCDebug(animation) << "evaluating the arm IK"; - _poses = AnimTwoBoneIK::evaluate(animVars, context, dt, triggersOut); - - //assert(_children.size() == 1); - //if (_children.size() != 1) { - // return _poses; - //} - -} \ No newline at end of file diff --git a/libraries/animation/src/AnimArmIK.h b/libraries/animation/src/AnimArmIK.h deleted file mode 100644 index 26f79a1b9c..0000000000 --- a/libraries/animation/src/AnimArmIK.h +++ /dev/null @@ -1,34 +0,0 @@ -// -// AnimArmIK.h -// -// Created by Angus Antley on 1/9/19. -// Copyright (c) 2019 High Fidelity, Inc. All rights reserved. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -#ifndef hifi_AnimArmIK_h -#define hifi_AnimArmIK_h - -//#include "AnimNode.h" -#include "AnimTwoBoneIK.h" -//#include "AnimChain.h" - -// Simple two bone IK chain -class AnimArmIK : public AnimTwoBoneIK { -public: - AnimArmIK(const QString& id, float alpha, bool enabled, float interpDuration, - const QString& baseJointName, const QString& midJointName, - const QString& tipJointName, const glm::vec3& midHingeAxis, - const QString& alphaVar, const QString& enabledVar, - const QString& endEffectorRotationVarVar, const QString& endEffectorPositionVarVar); - virtual ~AnimArmIK(); - virtual const AnimPoseVec& evaluate(const AnimVariantMap& animVars, const AnimContext& context, float dt, AnimVariantMap& triggersOut) override; - -protected: - -}; - -#endif // hifi_AnimArmIK_h - diff --git a/libraries/animation/src/AnimContext.h b/libraries/animation/src/AnimContext.h index 2c5b010f1b..e3ab5d9788 100644 --- a/libraries/animation/src/AnimContext.h +++ b/libraries/animation/src/AnimContext.h @@ -28,7 +28,6 @@ enum class AnimNodeType { InverseKinematics, DefaultPose, TwoBoneIK, - ArmIK, SplineIK, PoleVectorConstraint, NumTypes diff --git a/libraries/animation/src/AnimNodeLoader.cpp b/libraries/animation/src/AnimNodeLoader.cpp index 707bf7b976..3518fe14e5 100644 --- a/libraries/animation/src/AnimNodeLoader.cpp +++ b/libraries/animation/src/AnimNodeLoader.cpp @@ -26,7 +26,6 @@ #include "AnimInverseKinematics.h" #include "AnimDefaultPose.h" #include "AnimTwoBoneIK.h" -#include "AnimArmIK.h" #include "AnimSplineIK.h" #include "AnimPoleVectorConstraint.h" @@ -65,7 +64,6 @@ static const char* animNodeTypeToString(AnimNode::Type type) { case AnimNode::Type::InverseKinematics: return "inverseKinematics"; case AnimNode::Type::DefaultPose: return "defaultPose"; case AnimNode::Type::TwoBoneIK: return "twoBoneIK"; - case AnimNode::Type::ArmIK: return "armIK"; case AnimNode::Type::SplineIK: return "splineIK"; case AnimNode::Type::PoleVectorConstraint: return "poleVectorConstraint"; case AnimNode::Type::NumTypes: return nullptr; @@ -129,7 +127,6 @@ static NodeLoaderFunc animNodeTypeToLoaderFunc(AnimNode::Type type) { case AnimNode::Type::InverseKinematics: return loadInverseKinematicsNode; case AnimNode::Type::DefaultPose: return loadDefaultPoseNode; case AnimNode::Type::TwoBoneIK: return loadTwoBoneIKNode; - case AnimNode::Type::ArmIK: return loadArmIKNode; case AnimNode::Type::SplineIK: return loadSplineIKNode; case AnimNode::Type::PoleVectorConstraint: return loadPoleVectorConstraintNode; case AnimNode::Type::NumTypes: return nullptr; @@ -148,7 +145,6 @@ static NodeProcessFunc animNodeTypeToProcessFunc(AnimNode::Type type) { case AnimNode::Type::InverseKinematics: return processDoNothing; case AnimNode::Type::DefaultPose: return processDoNothing; case AnimNode::Type::TwoBoneIK: return processDoNothing; - case AnimNode::Type::ArmIK: return processDoNothing; case AnimNode::Type::SplineIK: return processDoNothing; case AnimNode::Type::PoleVectorConstraint: return processDoNothing; case AnimNode::Type::NumTypes: return nullptr; @@ -630,26 +626,6 @@ static AnimNode::Pointer loadSplineIKNode(const QJsonObject& jsonObj, const QStr return node; } -static AnimNode::Pointer loadArmIKNode(const QJsonObject& jsonObj, const QString& id, const QUrl& jsonUrl) { - READ_FLOAT(alpha, jsonObj, id, jsonUrl, nullptr); - READ_BOOL(enabled, jsonObj, id, jsonUrl, nullptr); - READ_FLOAT(interpDuration, jsonObj, id, jsonUrl, nullptr); - READ_STRING(baseJointName, jsonObj, id, jsonUrl, nullptr); - READ_STRING(midJointName, jsonObj, id, jsonUrl, nullptr); - READ_STRING(tipJointName, jsonObj, id, jsonUrl, nullptr); - READ_VEC3(midHingeAxis, jsonObj, id, jsonUrl, nullptr); - READ_STRING(alphaVar, jsonObj, id, jsonUrl, nullptr); - READ_STRING(enabledVar, jsonObj, id, jsonUrl, nullptr); - READ_STRING(endEffectorRotationVarVar, jsonObj, id, jsonUrl, nullptr); - READ_STRING(endEffectorPositionVarVar, jsonObj, id, jsonUrl, nullptr); - - auto node = std::make_shared(id, alpha, enabled, interpDuration, - baseJointName, midJointName, tipJointName, midHingeAxis, - alphaVar, enabledVar, - endEffectorRotationVarVar, endEffectorPositionVarVar); - return node; -} - static AnimNode::Pointer loadTwoBoneIKNode(const QJsonObject& jsonObj, const QString& id, const QUrl& jsonUrl) { READ_FLOAT(alpha, jsonObj, id, jsonUrl, nullptr); READ_BOOL(enabled, jsonObj, id, jsonUrl, nullptr); diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index 188f2aa790..e224c4f571 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -1462,8 +1462,9 @@ void Rig::updateHands(bool leftHandEnabled, bool rightHandEnabled, bool hipsEnab if (ENABLE_POLE_VECTORS && handJointIndex >= 0 && armJointIndex >= 0 && elbowJointIndex >= 0 && oppositeArmJointIndex >= 0) { //#ifdef FAKE_Q_OS_ANDROID #ifdef Q_OS_ANDROID + bool isLeft = true; float poleTheta; - bool usePoleTheta = calculateElbowPoleVectorOptimized(handJointIndex, elbowJointIndex, armJointIndex, true, poleTheta); + bool usePoleTheta = calculateElbowPoleVectorOptimized(handJointIndex, elbowJointIndex, armJointIndex, isLeft, poleTheta); if (usePoleTheta) { _animVars.set("leftHandPoleVectorEnabled", true); _animVars.set("leftHandPoleReferenceVector", Vectors::UNIT_X); @@ -1532,8 +1533,9 @@ void Rig::updateHands(bool leftHandEnabled, bool rightHandEnabled, bool hipsEnab //#ifdef FAKE_Q_OS_ANDROID #ifdef Q_OS_ANDROID + isLeft = false; float poleTheta; - bool usePoleTheta = calculateElbowPoleVectorOptimized(handJointIndex, elbowJointIndex, armJointIndex, false, poleTheta); + bool usePoleTheta = calculateElbowPoleVectorOptimized(handJointIndex, elbowJointIndex, armJointIndex, isLeft, poleTheta); if (usePoleTheta) { _animVars.set("rightHandPoleVectorEnabled", true); _animVars.set("rightHandPoleReferenceVector", -Vectors::UNIT_X); @@ -1719,13 +1721,6 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s // lower y with x center lower angle // lower y with x out higher angle - glm::vec3 referenceVector; - if (left) { - referenceVector = Vectors::UNIT_X; - } else { - referenceVector = -Vectors::UNIT_X; - } - AnimPose handPose = _externalPoseSet._absolutePoses[handIndex]; AnimPose shoulderPose = _externalPoseSet._absolutePoses[shoulderIndex]; AnimPose elbowPose = _externalPoseSet._absolutePoses[elbowIndex]; @@ -1772,7 +1767,7 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s theta *= -1.0f; } - // now we calculate the contribution of the hand + // now we calculate the contribution of the hand rotation relative to the arm glm::quat relativeHandRotation = (elbowPose.inverse() * handPose).rot(); if (relativeHandRotation.w < 0.0f) { relativeHandRotation *= -1.0f; @@ -1862,9 +1857,9 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s float flexCorrection = 0.0f; if (left) { if (_flexThetaRunningAverageLeft > FLEX_BOUNDARY) { - flexCorrection = ((_flexThetaRunningAverageLeft - FLEX_BOUNDARY) / PI) * 90.0f; + flexCorrection = ((_flexThetaRunningAverageLeft - FLEX_BOUNDARY) / PI) * 180.0f; } else if (_flexThetaRunningAverageLeft < EXTEND_BOUNDARY) { - flexCorrection = ((_flexThetaRunningAverageLeft - EXTEND_BOUNDARY) / PI) * 90.0f; + flexCorrection = ((_flexThetaRunningAverageLeft - EXTEND_BOUNDARY) / PI) * 180.0f; } if (fabs(flexCorrection) > 30.0f) { flexCorrection = glm::sign(flexCorrection) * 30.0f; @@ -1882,7 +1877,6 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s theta -= flexCorrection; } - const float TWIST_ULNAR_DEADZONE = 0.0f; const float ULNAR_BOUNDARY_MINUS = -PI / 6.0f; const float ULNAR_BOUNDARY_PLUS = PI / 6.0f; float ulnarDiff = 0.0f; @@ -1894,30 +1888,28 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s ulnarDiff = _ulnarRadialThetaRunningAverageLeft - ULNAR_BOUNDARY_MINUS; } if (fabs(ulnarDiff) > 0.0f) { - if (fabs(_twistThetaRunningAverageLeft) > TWIST_ULNAR_DEADZONE) { - float twistCoefficient = (fabs(_twistThetaRunningAverageLeft) / (PI / 20.0f)); - if (twistCoefficient > 1.0f) { - twistCoefficient = 1.0f; - } - if (left) { - if (trueTwistTheta < 0.0f) { - ulnarCorrection -= glm::sign(ulnarDiff) * (fabs(ulnarDiff) / PI) * 40.0f * twistCoefficient; - } else { - ulnarCorrection += glm::sign(ulnarDiff) * (fabs(ulnarDiff) / PI) * 40.0f * twistCoefficient; - } - } else { - // right hand - if (trueTwistTheta > 0.0f) { - ulnarCorrection -= glm::sign(ulnarDiff) * (fabs(ulnarDiff) / PI) * 40.0f * twistCoefficient; - } else { - ulnarCorrection += glm::sign(ulnarDiff) * (fabs(ulnarDiff) / PI) * 40.0f * twistCoefficient; - } - } - if (fabsf(ulnarCorrection) > 20.0f) { - ulnarCorrection = glm::sign(ulnarCorrection) * 20.0f; - } - theta += ulnarCorrection; + float twistCoefficient = (fabs(_twistThetaRunningAverageLeft) / (PI / 20.0f)); + if (twistCoefficient > 1.0f) { + twistCoefficient = 1.0f; } + if (left) { + if (trueTwistTheta < 0.0f) { + ulnarCorrection -= glm::sign(ulnarDiff) * (fabs(ulnarDiff) / PI) * 40.0f * twistCoefficient; + } else { + ulnarCorrection += glm::sign(ulnarDiff) * (fabs(ulnarDiff) / PI) * 40.0f * twistCoefficient; + } + } else { + // right hand + if (trueTwistTheta > 0.0f) { + ulnarCorrection -= glm::sign(ulnarDiff) * (fabs(ulnarDiff) / PI) * 40.0f * twistCoefficient; + } else { + ulnarCorrection += glm::sign(ulnarDiff) * (fabs(ulnarDiff) / PI) * 40.0f * twistCoefficient; + } + } + if (fabsf(ulnarCorrection) > 20.0f) { + ulnarCorrection = glm::sign(ulnarCorrection) * 20.0f; + } + theta += ulnarCorrection; } } else { if (_ulnarRadialThetaRunningAverageRight > ULNAR_BOUNDARY_PLUS) { @@ -1926,34 +1918,31 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s ulnarDiff = _ulnarRadialThetaRunningAverageRight - ULNAR_BOUNDARY_MINUS; } if (fabs(ulnarDiff) > 0.0f) { - if (fabs(_twistThetaRunningAverageRight) > TWIST_ULNAR_DEADZONE) { - float twistCoefficient = (fabs(_twistThetaRunningAverageRight) / (PI / 20.0f)); - if (twistCoefficient > 1.0f) { - twistCoefficient = 1.0f; - } - if (left) { - if (trueTwistTheta < 0.0f) { - ulnarCorrection -= glm::sign(ulnarDiff) * (fabs(ulnarDiff) / PI) * 90.0f * twistCoefficient; - } else { - ulnarCorrection += glm::sign(ulnarDiff) * (fabs(ulnarDiff) / PI) * 90.0f * twistCoefficient; - } - } else { - // right hand - if (trueTwistTheta > 0.0f) { - ulnarCorrection -= glm::sign(ulnarDiff) * (fabs(ulnarDiff) / PI) * 90.0f * twistCoefficient; - } else { - ulnarCorrection += glm::sign(ulnarDiff) * (fabs(ulnarDiff) / PI) * 90.0f * twistCoefficient; - } - } - if (fabsf(ulnarCorrection) > 20.0f) { - ulnarCorrection = glm::sign(ulnarCorrection) * 20.0f; - } - theta += ulnarCorrection; + float twistCoefficient = (fabs(_twistThetaRunningAverageRight) / (PI / 20.0f)); + if (twistCoefficient > 1.0f) { + twistCoefficient = 1.0f; } + if (left) { + if (trueTwistTheta < 0.0f) { + ulnarCorrection -= glm::sign(ulnarDiff) * (fabs(ulnarDiff) / PI) * 40.0f * twistCoefficient; + } else { + ulnarCorrection += glm::sign(ulnarDiff) * (fabs(ulnarDiff) / PI) * 40.0f * twistCoefficient; + } + } else { + // right hand + if (trueTwistTheta > 0.0f) { + ulnarCorrection -= glm::sign(ulnarDiff) * (fabs(ulnarDiff) / PI) * 40.0f * twistCoefficient; + } else { + ulnarCorrection += glm::sign(ulnarDiff) * (fabs(ulnarDiff) / PI) * 40.0f * twistCoefficient; + } + } + if (fabsf(ulnarCorrection) > 20.0f) { + ulnarCorrection = glm::sign(ulnarCorrection) * 20.0f; + } + theta += ulnarCorrection; } } - // remember direction of travel. const float TWIST_DEADZONE = (4 * PI) / 9.0f; float twistCorrection = 0.0f; if (left) { @@ -1965,14 +1954,13 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s twistCorrection = glm::sign(_twistThetaRunningAverageRight) * ((fabsf(_twistThetaRunningAverageRight) - TWIST_DEADZONE) / PI) * 80.0f; } } + // limit the twist correction if (fabsf(twistCorrection) > 30.0f) { theta += glm::sign(twistCorrection) * 30.0f; } else { theta += twistCorrection; } - //qCDebug(animation) << "twist correction: " << twistCorrection << " flex correction: " << flexCorrection << " ulnar correction " << ulnarCorrection; - // global limiting if (left) { // final global smoothing @@ -1988,7 +1976,6 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s } // convert to radians and make 180 0 to match pole vector theta float thetaRadians = ((180.0f - _lastThetaLeft) / 180.0f)*PI; - //_animVars.set("thetaLeftElbow", thetaRadians); poleTheta = thetaRadians; } else { @@ -2005,7 +1992,6 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s } // convert to radians and make 180 0 to match pole vector theta float thetaRadians = ((180.0f - _lastThetaRight) / 180.0f)*PI; - //_animVars.set("thetaRightElbow", thetaRadians); poleTheta = thetaRadians; } From d78f253d24063a0c3d4cea95ff8e92bb28a04e60 Mon Sep 17 00:00:00 2001 From: amantley Date: Fri, 15 Feb 2019 17:43:53 -0800 Subject: [PATCH 084/112] code to generate pole vector from theta --- interface/src/avatar/MyAvatar.cpp | 7 ++--- .../src/AnimPoleVectorConstraint.cpp | 5 ++-- libraries/animation/src/Rig.cpp | 30 ++++++++++++++----- 3 files changed, 27 insertions(+), 15 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index ea5f2163fe..c2e7292a0a 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -2943,8 +2943,7 @@ void MyAvatar::setAnimGraphUrl(const QUrl& url) { connect(&(_skeletonModel->getRig()), SIGNAL(onLoadComplete()), this, SLOT(animGraphLoaded())); } -#define FAKE_Q_OS_ANDROID - +#define USE_Q_OS_ANDROID void MyAvatar::initAnimGraph() { QUrl graphUrl; if (!_prefOverrideAnimGraphUrl.get().isEmpty()) { @@ -2953,8 +2952,8 @@ void MyAvatar::initAnimGraph() { graphUrl = _fstAnimGraphOverrideUrl; } else { graphUrl = PathUtils::resourcesUrl("avatar/avatar-animation.json"); - //#ifdef FAKE_Q_OS_ANDROID - #ifdef Q_OS_ANDROID + + #if defined(Q_OS_ANDROID) || defined(USE_Q_OS_ANDROID) graphUrl = PathUtils::resourcesUrl("avatar/avatar-animation_withSplineIKNode.json"); #endif } diff --git a/libraries/animation/src/AnimPoleVectorConstraint.cpp b/libraries/animation/src/AnimPoleVectorConstraint.cpp index 998368a0c6..505471efdd 100644 --- a/libraries/animation/src/AnimPoleVectorConstraint.cpp +++ b/libraries/animation/src/AnimPoleVectorConstraint.cpp @@ -13,7 +13,7 @@ #include "AnimUtil.h" #include "GLMHelpers.h" -#define FAKE_Q_OS_ANDROID true; +#define USE_Q_OS_ANDROID const float FRAMES_PER_SECOND = 30.0f; const float INTERP_DURATION = 6.0f; @@ -114,8 +114,7 @@ const AnimPoseVec& AnimPoleVectorConstraint::evaluate(const AnimVariantMap& anim glm::vec3 poleVectorProj = poleVector - glm::dot(poleVector, unitAxis) * unitAxis; float poleVectorProjLength = glm::length(poleVectorProj); -//#ifdef FAKE_Q_OS_ANDROID -#ifdef Q_OS_ANDROID +#if defined(Q_OS_ANDROID) || defined(USE_Q_OS_ANDROID) // get theta set by optimized ik for Quest if ((_skeleton->nameToJointIndex("RightHand") == _tipJointIndex) || (_skeleton->nameToJointIndex("LeftHand") == _tipJointIndex)) { diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index e224c4f571..ab35186bfd 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -34,8 +34,7 @@ #include "IKTarget.h" #include "PathUtils.h" -#define FAKE_Q_OS_ANDROID true; - +#define USE_Q_OS_ANDROID static int nextRigId = 1; static std::map rigRegistry; static std::mutex rigRegistryMutex; @@ -1460,8 +1459,7 @@ void Rig::updateHands(bool leftHandEnabled, bool rightHandEnabled, bool hipsEnab int elbowJointIndex = _animSkeleton->nameToJointIndex("LeftForeArm"); int oppositeArmJointIndex = _animSkeleton->nameToJointIndex("RightArm"); if (ENABLE_POLE_VECTORS && handJointIndex >= 0 && armJointIndex >= 0 && elbowJointIndex >= 0 && oppositeArmJointIndex >= 0) { - //#ifdef FAKE_Q_OS_ANDROID - #ifdef Q_OS_ANDROID + #if defined(Q_OS_ANDROID) || defined(USE_Q_OS_ANDROID) bool isLeft = true; float poleTheta; bool usePoleTheta = calculateElbowPoleVectorOptimized(handJointIndex, elbowJointIndex, armJointIndex, isLeft, poleTheta); @@ -1531,9 +1529,8 @@ void Rig::updateHands(bool leftHandEnabled, bool rightHandEnabled, bool hipsEnab if (ENABLE_POLE_VECTORS && handJointIndex >= 0 && armJointIndex >= 0 && elbowJointIndex >= 0 && oppositeArmJointIndex >= 0) { - //#ifdef FAKE_Q_OS_ANDROID - #ifdef Q_OS_ANDROID - isLeft = false; + #if defined(Q_OS_ANDROID) || defined(USE_Q_OS_ANDROID) + bool isLeft = false; float poleTheta; bool usePoleTheta = calculateElbowPoleVectorOptimized(handJointIndex, elbowJointIndex, armJointIndex, isLeft, poleTheta); if (usePoleTheta) { @@ -1848,7 +1845,7 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s } if (!left) { - qCDebug(animation) << "flex ave: " << (_flexThetaRunningAverageRight / PI) * 180.0f << " twist ave: " << (_twistThetaRunningAverageRight / PI) * 180.0f << " ulnar deviation ave: " << (_ulnarRadialThetaRunningAverageRight / PI) * 180.0f; + //qCDebug(animation) << "flex ave: " << (_flexThetaRunningAverageRight / PI) * 180.0f << " twist ave: " << (_twistThetaRunningAverageRight / PI) * 180.0f << " ulnar deviation ave: " << (_ulnarRadialThetaRunningAverageRight / PI) * 180.0f; } const float POWER = 2.0f; @@ -1995,6 +1992,23 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s poleTheta = thetaRadians; } + float xValue = sin(poleTheta); + float yValue = cos(poleTheta); + float zValue = 0.0f; + glm::vec3 thetaVector(xValue, yValue, zValue); + glm::vec3 xAxis = glm::cross(Vectors::UNIT_Y, armToHand); + glm::vec3 up = glm::cross(armToHand, xAxis); + glm::quat armAxisRotation; + glm::vec3 u, v, w; + glm::vec3 fwd = armToHand/glm::length(armToHand); + + generateBasisVectors(Vectors::UNIT_Y, fwd, u, v, w); + AnimPose armAxisPose(glm::mat4(glm::vec4(w, 0.0f), glm::vec4(u, 0.0f), glm::vec4(v, 0.0f), glm::vec4(glm::vec3(0.0f, 0.0f, 0.0f), 1.0f))); + glm::vec3 pole = armAxisPose * thetaVector; + + qCDebug(animation) << "the pole from theta is " << pole; + + return true; } From 0982c37c5e0d089524c30d14b2d6fa1c1f836bb3 Mon Sep 17 00:00:00 2001 From: Angus Antley Date: Sat, 16 Feb 2019 14:50:47 -0800 Subject: [PATCH 085/112] took out the theta animvar and just use theta converted to pole vector --- .../src/AnimPoleVectorConstraint.cpp | 40 ++------ libraries/animation/src/Rig.cpp | 99 +++++++++++-------- libraries/animation/src/Rig.h | 2 +- 3 files changed, 64 insertions(+), 77 deletions(-) diff --git a/libraries/animation/src/AnimPoleVectorConstraint.cpp b/libraries/animation/src/AnimPoleVectorConstraint.cpp index 505471efdd..7b60d6984b 100644 --- a/libraries/animation/src/AnimPoleVectorConstraint.cpp +++ b/libraries/animation/src/AnimPoleVectorConstraint.cpp @@ -114,17 +114,14 @@ const AnimPoseVec& AnimPoleVectorConstraint::evaluate(const AnimVariantMap& anim glm::vec3 poleVectorProj = poleVector - glm::dot(poleVector, unitAxis) * unitAxis; float poleVectorProjLength = glm::length(poleVectorProj); -#if defined(Q_OS_ANDROID) || defined(USE_Q_OS_ANDROID) + // double check for zero length vectors or vectors parallel to rotaiton axis. + if (axisLength > MIN_LENGTH && refVectorLength > MIN_LENGTH && sideVectorLength > MIN_LENGTH && + refVectorProjLength > MIN_LENGTH && poleVectorProjLength > MIN_LENGTH) { - // get theta set by optimized ik for Quest - if ((_skeleton->nameToJointIndex("RightHand") == _tipJointIndex) || (_skeleton->nameToJointIndex("LeftHand") == _tipJointIndex)) { + float dot = glm::clamp(glm::dot(refVectorProj / refVectorProjLength, poleVectorProj / poleVectorProjLength), 0.0f, 1.0f); + float sideDot = glm::dot(poleVector, sideVector); + float theta = copysignf(1.0f, sideDot) * acosf(dot); - float theta; - if (_skeleton->nameToJointIndex("LeftHand") == _tipJointIndex) { - theta = animVars.lookup("thetaLeftElbow", 0.0f); - } else if (_skeleton->nameToJointIndex("RightHand") == _tipJointIndex) { - theta = animVars.lookup("thetaRightElbow", 0.0f); - } glm::quat deltaRot = glm::angleAxis(theta, unitAxis); @@ -136,30 +133,7 @@ const AnimPoseVec& AnimPoleVectorConstraint::evaluate(const AnimVariantMap& anim glm::quat relTipRot = glm::inverse(midPose.rot()) * glm::inverse(deltaRot) * tipPose.rot(); ikChain.setRelativePoseAtJointIndex(_tipJointIndex, AnimPose(relTipRot, underPoses[_tipJointIndex].trans())); } - -#else - // double check for zero length vectors or vectors parallel to rotaiton axis. - if (axisLength > MIN_LENGTH && refVectorLength > MIN_LENGTH && sideVectorLength > MIN_LENGTH && - refVectorProjLength > MIN_LENGTH && poleVectorProjLength > MIN_LENGTH) { - - float dot = glm::clamp(glm::dot(refVectorProj / refVectorProjLength, poleVectorProj / poleVectorProjLength), 0.0f, 1.0f); - float sideDot = glm::dot(poleVector, sideVector); - float theta = copysignf(1.0f, sideDot) * acosf(dot); - - - - glm::quat deltaRot = glm::angleAxis(theta, unitAxis); - - // transform result back into parent relative frame. - glm::quat relBaseRot = glm::inverse(baseParentPose.rot()) * deltaRot * basePose.rot(); - ikChain.setRelativePoseAtJointIndex(_baseJointIndex, AnimPose(relBaseRot, underPoses[_baseJointIndex].trans())); - - glm::quat relTipRot = glm::inverse(midPose.rot()) * glm::inverse(deltaRot) * tipPose.rot(); - ikChain.setRelativePoseAtJointIndex(_tipJointIndex, AnimPose(relTipRot, underPoses[_tipJointIndex].trans())); - } - -#endif - + // start off by initializing output poses with the underPoses _poses = underPoses; diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index ab35186bfd..bd990470e2 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -1459,20 +1459,13 @@ void Rig::updateHands(bool leftHandEnabled, bool rightHandEnabled, bool hipsEnab int elbowJointIndex = _animSkeleton->nameToJointIndex("LeftForeArm"); int oppositeArmJointIndex = _animSkeleton->nameToJointIndex("RightArm"); if (ENABLE_POLE_VECTORS && handJointIndex >= 0 && armJointIndex >= 0 && elbowJointIndex >= 0 && oppositeArmJointIndex >= 0) { - #if defined(Q_OS_ANDROID) || defined(USE_Q_OS_ANDROID) - bool isLeft = true; - float poleTheta; - bool usePoleTheta = calculateElbowPoleVectorOptimized(handJointIndex, elbowJointIndex, armJointIndex, isLeft, poleTheta); - if (usePoleTheta) { - _animVars.set("leftHandPoleVectorEnabled", true); - _animVars.set("leftHandPoleReferenceVector", Vectors::UNIT_X); - _animVars.set("thetaLeftElbow", poleTheta); - } else { - _animVars.set("leftHandPoleVectorEnabled", false); - } - #else glm::vec3 poleVector; +#if defined(Q_OS_ANDROID) || defined(USE_Q_OS_ANDROID) + bool isLeft = true; + bool usePoleVector = calculateElbowPoleVectorOptimized(handJointIndex, elbowJointIndex, armJointIndex, isLeft, poleVector); +#else bool usePoleVector = calculateElbowPoleVector(handJointIndex, elbowJointIndex, armJointIndex, oppositeArmJointIndex, poleVector); +#endif if (usePoleVector) { glm::vec3 sensorPoleVector = transformVectorFast(rigToSensorMatrix, poleVector); _animVars.set("leftHandPoleVectorEnabled", true); @@ -1481,8 +1474,6 @@ void Rig::updateHands(bool leftHandEnabled, bool rightHandEnabled, bool hipsEnab } else { _animVars.set("leftHandPoleVectorEnabled", false); } - #endif - } else { _animVars.set("leftHandPoleVectorEnabled", false); } @@ -1528,21 +1519,13 @@ void Rig::updateHands(bool leftHandEnabled, bool rightHandEnabled, bool hipsEnab int oppositeArmJointIndex = _animSkeleton->nameToJointIndex("LeftArm"); if (ENABLE_POLE_VECTORS && handJointIndex >= 0 && armJointIndex >= 0 && elbowJointIndex >= 0 && oppositeArmJointIndex >= 0) { - - #if defined(Q_OS_ANDROID) || defined(USE_Q_OS_ANDROID) - bool isLeft = false; - float poleTheta; - bool usePoleTheta = calculateElbowPoleVectorOptimized(handJointIndex, elbowJointIndex, armJointIndex, isLeft, poleTheta); - if (usePoleTheta) { - _animVars.set("rightHandPoleVectorEnabled", true); - _animVars.set("rightHandPoleReferenceVector", -Vectors::UNIT_X); - _animVars.set("thetaRightElbow", poleTheta); - } else { - _animVars.set("rightHandPoleVectorEnabled", false); - } - #else glm::vec3 poleVector; +#if defined(Q_OS_ANDROID) || defined(USE_Q_OS_ANDROID) + bool isLeft = false; + bool usePoleVector = calculateElbowPoleVectorOptimized(handJointIndex, elbowJointIndex, armJointIndex, isLeft, poleVector); +#else bool usePoleVector = calculateElbowPoleVector(handJointIndex, elbowJointIndex, armJointIndex, oppositeArmJointIndex, poleVector); +#endif if (usePoleVector) { glm::vec3 sensorPoleVector = transformVectorFast(rigToSensorMatrix, poleVector); _animVars.set("rightHandPoleVectorEnabled", true); @@ -1551,8 +1534,6 @@ void Rig::updateHands(bool leftHandEnabled, bool rightHandEnabled, bool hipsEnab } else { _animVars.set("rightHandPoleVectorEnabled", false); } - - #endif } else { _animVars.set("rightHandPoleVectorEnabled", false); } @@ -1710,7 +1691,7 @@ void Rig::updateEyeJoint(int index, const glm::vec3& modelTranslation, const glm } } -bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int shoulderIndex, bool left, float& poleTheta) { +bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int shoulderIndex, bool left, glm::vec3& poleVector) { // get the default poses for the upper and lower arm // then use this length to judge how far the hand is away from the shoulder. // then create weights that make the elbow angle less when the x value is large in either direction. @@ -1735,6 +1716,13 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s const float zWeightBottom = -100.0f; const glm::vec3 weights(-50.0f, 60.0f, 260.0f); glm::vec3 armToHand = handPose.trans() - shoulderPose.trans(); + glm::vec3 unitAxis; + float axisLength = glm::length(armToHand); + if (axisLength > 0.0f) { + unitAxis = armToHand / axisLength; + } else { + unitAxis = Vectors::UNIT_Y; + } float yFactor = (fabsf(armToHand[1] / defaultArmLength) * weights[1]) + biases[1]; float zFactor; @@ -1764,8 +1752,24 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s theta *= -1.0f; } + float deltaTheta = 0.0f; + if (left) { + deltaTheta = theta - _lastThetaLeft; + } else { + deltaTheta = theta - _lastThetaRight; + } + float deltaThetaRadians = (deltaTheta / 180.0f)*PI; + AnimPose deltaRot(glm::angleAxis(deltaThetaRadians, unitAxis), glm::vec3()); + AnimPose relMid = shoulderPose.inverse() * elbowPose; + AnimPose updatedBase = shoulderPose * deltaRot; + AnimPose newAbsMid = updatedBase * relMid; + + // now we calculate the contribution of the hand rotation relative to the arm - glm::quat relativeHandRotation = (elbowPose.inverse() * handPose).rot(); + // we are adding in the delta rotation so that we have the hand correction relative to the + // latest theta for hand position + glm::quat relativeHandRotation = (newAbsMid.inverse() * handPose).rot(); + //glm::quat relativeHandRotation = (elbowPose.inverse() * handPose).rot(); if (relativeHandRotation.w < 0.0f) { relativeHandRotation *= -1.0f; } @@ -1959,6 +1963,7 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s } // global limiting + float thetaRadians = 0.0f; if (left) { // final global smoothing _lastThetaLeft = 0.5f * _lastThetaLeft + 0.5f * theta; @@ -1972,9 +1977,7 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s _lastThetaLeft = glm::sign(_lastThetaLeft) * 175.0f; } // convert to radians and make 180 0 to match pole vector theta - float thetaRadians = ((180.0f - _lastThetaLeft) / 180.0f)*PI; - poleTheta = thetaRadians; - + thetaRadians = ((180.0f - _lastThetaLeft) / 180.0f)*PI; } else { // final global smoothing _lastThetaRight = 0.5f * _lastThetaRight + 0.5f * theta; @@ -1988,26 +1991,32 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s _lastThetaRight = glm::sign(_lastThetaRight) * 175.0f; } // convert to radians and make 180 0 to match pole vector theta - float thetaRadians = ((180.0f - _lastThetaRight) / 180.0f)*PI; - poleTheta = thetaRadians; + thetaRadians = ((180.0f - _lastThetaRight) / 180.0f)*PI; } - float xValue = sin(poleTheta); - float yValue = cos(poleTheta); + float xValue = -1.0f * sin(thetaRadians); + float yValue = -1.0f * cos(thetaRadians); float zValue = 0.0f; glm::vec3 thetaVector(xValue, yValue, zValue); + //glm::vec3 thetaVector(1.0f, 0.0f, 0.0f); + glm::vec3 xAxis = glm::cross(Vectors::UNIT_Y, armToHand); glm::vec3 up = glm::cross(armToHand, xAxis); glm::quat armAxisRotation; glm::vec3 u, v, w; glm::vec3 fwd = armToHand/glm::length(armToHand); - generateBasisVectors(Vectors::UNIT_Y, fwd, u, v, w); - AnimPose armAxisPose(glm::mat4(glm::vec4(w, 0.0f), glm::vec4(u, 0.0f), glm::vec4(v, 0.0f), glm::vec4(glm::vec3(0.0f, 0.0f, 0.0f), 1.0f))); - glm::vec3 pole = armAxisPose * thetaVector; - - qCDebug(animation) << "the pole from theta is " << pole; + generateBasisVectors(fwd, Vectors::UNIT_Y, u, v, w); + AnimPose armAxisPose(glm::mat4(glm::vec4(-w, 0.0f), glm::vec4(v, 0.0f), glm::vec4(u, 0.0f), glm::vec4(glm::vec3(0.0f, 0.0f, 0.0f), 1.0f))); + poleVector = armAxisPose * thetaVector; + if (left) { + qCDebug(animation) << "theta vector " << thetaVector; + //qCDebug(animation) << "fwd " << fwd; + //qCDebug(animation) << "the x is " << w; + //qCDebug(animation) << "the y is " << v; + //qCDebug(animation) << "the z is " << u; + } return true; } @@ -2082,6 +2091,10 @@ bool Rig::calculateElbowPoleVector(int handIndex, int elbowIndex, int armIndex, correctionVector = forwardAmount * frontVector; } poleVector = glm::normalize(attenuationVector + fullPoleVector + correctionVector); + + if (handIndex == _animSkeleton->nameToJointIndex("LeftHand")) { + qCDebug(animation) << "the pole vector is " << poleVector; + } return true; } diff --git a/libraries/animation/src/Rig.h b/libraries/animation/src/Rig.h index 4dce28f7ae..693aa732fa 100644 --- a/libraries/animation/src/Rig.h +++ b/libraries/animation/src/Rig.h @@ -258,7 +258,7 @@ protected: void calcAnimAlpha(float speed, const std::vector& referenceSpeeds, float* alphaOut) const; bool calculateElbowPoleVector(int handIndex, int elbowIndex, int armIndex, int oppositeArmIndex, glm::vec3& poleVector) const; - bool calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int shoulderIndex, bool left, float& poleTheta); + bool calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int shoulderIndex, bool left, glm::vec3& poleVector); glm::vec3 calculateKneePoleVector(int footJointIndex, int kneeJoint, int upLegIndex, int hipsIndex, const AnimPose& targetFootPose) const; glm::vec3 deflectHandFromTorso(const glm::vec3& handPosition, const HFMJointShapeInfo& hipsShapeInfo, const HFMJointShapeInfo& spineShapeInfo, const HFMJointShapeInfo& spine1ShapeInfo, const HFMJointShapeInfo& spine2ShapeInfo) const; From e1dfd7d28889ce5c6d18e0424aef56a1f0f333ba Mon Sep 17 00:00:00 2001 From: Angus Antley Date: Sat, 16 Feb 2019 23:40:16 -0800 Subject: [PATCH 086/112] cleanup white space --- libraries/animation/src/AnimNodeLoader.cpp | 1 - .../src/AnimPoleVectorConstraint.cpp | 5 +- libraries/animation/src/AnimSplineIK.cpp | 1 - libraries/animation/src/AnimSplineIK.h | 2 +- libraries/animation/src/Rig.cpp | 51 ++++++++----------- libraries/animation/src/Rig.h | 8 +-- 6 files changed, 25 insertions(+), 43 deletions(-) diff --git a/libraries/animation/src/AnimNodeLoader.cpp b/libraries/animation/src/AnimNodeLoader.cpp index 3518fe14e5..b637d131f8 100644 --- a/libraries/animation/src/AnimNodeLoader.cpp +++ b/libraries/animation/src/AnimNodeLoader.cpp @@ -42,7 +42,6 @@ static AnimNode::Pointer loadManipulatorNode(const QJsonObject& jsonObj, const Q static AnimNode::Pointer loadInverseKinematicsNode(const QJsonObject& jsonObj, const QString& id, const QUrl& jsonUrl); static AnimNode::Pointer loadDefaultPoseNode(const QJsonObject& jsonObj, const QString& id, const QUrl& jsonUrl); static AnimNode::Pointer loadTwoBoneIKNode(const QJsonObject& jsonObj, const QString& id, const QUrl& jsonUrl); -static AnimNode::Pointer loadArmIKNode(const QJsonObject& jsonObj, const QString& id, const QUrl& jsonUrl); static AnimNode::Pointer loadSplineIKNode(const QJsonObject& jsonObj, const QString& id, const QUrl& jsonUrl); static AnimNode::Pointer loadPoleVectorConstraintNode(const QJsonObject& jsonObj, const QString& id, const QUrl& jsonUrl); diff --git a/libraries/animation/src/AnimPoleVectorConstraint.cpp b/libraries/animation/src/AnimPoleVectorConstraint.cpp index 7b60d6984b..f017fe2348 100644 --- a/libraries/animation/src/AnimPoleVectorConstraint.cpp +++ b/libraries/animation/src/AnimPoleVectorConstraint.cpp @@ -13,7 +13,6 @@ #include "AnimUtil.h" #include "GLMHelpers.h" -#define USE_Q_OS_ANDROID const float FRAMES_PER_SECOND = 30.0f; const float INTERP_DURATION = 6.0f; @@ -122,8 +121,6 @@ const AnimPoseVec& AnimPoleVectorConstraint::evaluate(const AnimVariantMap& anim float sideDot = glm::dot(poleVector, sideVector); float theta = copysignf(1.0f, sideDot) * acosf(dot); - - glm::quat deltaRot = glm::angleAxis(theta, unitAxis); // transform result back into parent relative frame. @@ -133,7 +130,7 @@ const AnimPoseVec& AnimPoleVectorConstraint::evaluate(const AnimVariantMap& anim glm::quat relTipRot = glm::inverse(midPose.rot()) * glm::inverse(deltaRot) * tipPose.rot(); ikChain.setRelativePoseAtJointIndex(_tipJointIndex, AnimPose(relTipRot, underPoses[_tipJointIndex].trans())); } - + // start off by initializing output poses with the underPoses _poses = underPoses; diff --git a/libraries/animation/src/AnimSplineIK.cpp b/libraries/animation/src/AnimSplineIK.cpp index 72dcbfc5e7..30e0a42e65 100644 --- a/libraries/animation/src/AnimSplineIK.cpp +++ b/libraries/animation/src/AnimSplineIK.cpp @@ -14,7 +14,6 @@ #include #include "AnimUtil.h" -static const float JOINT_CHAIN_INTERP_TIME = 0.5f; static const float FRAMES_PER_SECOND = 30.0f; AnimSplineIK::AnimSplineIK(const QString& id, float alpha, bool enabled, float interpDuration, diff --git a/libraries/animation/src/AnimSplineIK.h b/libraries/animation/src/AnimSplineIK.h index bca0f7fe77..a4d8da37ca 100644 --- a/libraries/animation/src/AnimSplineIK.h +++ b/libraries/animation/src/AnimSplineIK.h @@ -57,8 +57,8 @@ protected: bool _enabled; float _interpDuration; QString _baseJointName; - QString _tipJointName; QString _midJointName; + QString _tipJointName; QString _basePositionVar; QString _baseRotationVar; QString _midPositionVar; diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index bd990470e2..ee8daef668 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -1462,7 +1462,7 @@ void Rig::updateHands(bool leftHandEnabled, bool rightHandEnabled, bool hipsEnab glm::vec3 poleVector; #if defined(Q_OS_ANDROID) || defined(USE_Q_OS_ANDROID) bool isLeft = true; - bool usePoleVector = calculateElbowPoleVectorOptimized(handJointIndex, elbowJointIndex, armJointIndex, isLeft, poleVector); + bool usePoleVector = calculateElbowPoleVectorOptimized(handJointIndex, elbowJointIndex, armJointIndex, isLeft, poleVector); #else bool usePoleVector = calculateElbowPoleVector(handJointIndex, elbowJointIndex, armJointIndex, oppositeArmJointIndex, poleVector); #endif @@ -1727,9 +1727,9 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s float zFactor; if (armToHand[1] > 0.0f) { - zFactor = weights[2] * glm::max(zStart - (armToHand[2] / defaultArmLength), 0.0f) * fabs(armToHand[1] / defaultArmLength); + zFactor = weights[2] * glm::max(zStart - (armToHand[2] / defaultArmLength), 0.0f) * fabsf(armToHand[1] / defaultArmLength); } else { - zFactor = zWeightBottom * glm::max(zStart - (armToHand[2] / defaultArmLength), 0.0f) * fabs(armToHand[1] / defaultArmLength); + zFactor = zWeightBottom * glm::max(zStart - (armToHand[2] / defaultArmLength), 0.0f) * fabsf(armToHand[1] / defaultArmLength); } float xFactor; @@ -1766,8 +1766,8 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s // now we calculate the contribution of the hand rotation relative to the arm - // we are adding in the delta rotation so that we have the hand correction relative to the - // latest theta for hand position + // we are adding in the delta rotation so that we have the hand correction relative to the + // latest theta for hand position glm::quat relativeHandRotation = (newAbsMid.inverse() * handPose).rot(); //glm::quat relativeHandRotation = (elbowPose.inverse() * handPose).rot(); if (relativeHandRotation.w < 0.0f) { @@ -1852,7 +1852,6 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s //qCDebug(animation) << "flex ave: " << (_flexThetaRunningAverageRight / PI) * 180.0f << " twist ave: " << (_twistThetaRunningAverageRight / PI) * 180.0f << " ulnar deviation ave: " << (_ulnarRadialThetaRunningAverageRight / PI) * 180.0f; } - const float POWER = 2.0f; const float FLEX_BOUNDARY = PI / 6.0f; const float EXTEND_BOUNDARY = -PI / 4.0f; float flexCorrection = 0.0f; @@ -1862,7 +1861,7 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s } else if (_flexThetaRunningAverageLeft < EXTEND_BOUNDARY) { flexCorrection = ((_flexThetaRunningAverageLeft - EXTEND_BOUNDARY) / PI) * 180.0f; } - if (fabs(flexCorrection) > 30.0f) { + if (fabsf(flexCorrection) > 30.0f) { flexCorrection = glm::sign(flexCorrection) * 30.0f; } theta += flexCorrection; @@ -1872,7 +1871,7 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s } else if (_flexThetaRunningAverageRight < EXTEND_BOUNDARY) { flexCorrection = ((_flexThetaRunningAverageRight - EXTEND_BOUNDARY) / PI) * 180.0f; } - if (fabs(flexCorrection) > 30.0f) { + if (fabsf(flexCorrection) > 30.0f) { flexCorrection = glm::sign(flexCorrection) * 30.0f; } theta -= flexCorrection; @@ -1888,23 +1887,23 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s } else if (_ulnarRadialThetaRunningAverageLeft < ULNAR_BOUNDARY_MINUS) { ulnarDiff = _ulnarRadialThetaRunningAverageLeft - ULNAR_BOUNDARY_MINUS; } - if (fabs(ulnarDiff) > 0.0f) { - float twistCoefficient = (fabs(_twistThetaRunningAverageLeft) / (PI / 20.0f)); + if (fabsf(ulnarDiff) > 0.0f) { + float twistCoefficient = (fabsf(_twistThetaRunningAverageLeft) / (PI / 20.0f)); if (twistCoefficient > 1.0f) { twistCoefficient = 1.0f; } if (left) { if (trueTwistTheta < 0.0f) { - ulnarCorrection -= glm::sign(ulnarDiff) * (fabs(ulnarDiff) / PI) * 40.0f * twistCoefficient; + ulnarCorrection -= glm::sign(ulnarDiff) * (fabsf(ulnarDiff) / PI) * 40.0f * twistCoefficient; } else { - ulnarCorrection += glm::sign(ulnarDiff) * (fabs(ulnarDiff) / PI) * 40.0f * twistCoefficient; + ulnarCorrection += glm::sign(ulnarDiff) * (fabsf(ulnarDiff) / PI) * 40.0f * twistCoefficient; } } else { // right hand if (trueTwistTheta > 0.0f) { - ulnarCorrection -= glm::sign(ulnarDiff) * (fabs(ulnarDiff) / PI) * 40.0f * twistCoefficient; + ulnarCorrection -= glm::sign(ulnarDiff) * (fabsf(ulnarDiff) / PI) * 40.0f * twistCoefficient; } else { - ulnarCorrection += glm::sign(ulnarDiff) * (fabs(ulnarDiff) / PI) * 40.0f * twistCoefficient; + ulnarCorrection += glm::sign(ulnarDiff) * (fabsf(ulnarDiff) / PI) * 40.0f * twistCoefficient; } } if (fabsf(ulnarCorrection) > 20.0f) { @@ -1918,23 +1917,23 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s } else if (_ulnarRadialThetaRunningAverageRight < ULNAR_BOUNDARY_MINUS) { ulnarDiff = _ulnarRadialThetaRunningAverageRight - ULNAR_BOUNDARY_MINUS; } - if (fabs(ulnarDiff) > 0.0f) { - float twistCoefficient = (fabs(_twistThetaRunningAverageRight) / (PI / 20.0f)); + if (fabsf(ulnarDiff) > 0.0f) { + float twistCoefficient = (fabsf(_twistThetaRunningAverageRight) / (PI / 20.0f)); if (twistCoefficient > 1.0f) { twistCoefficient = 1.0f; } if (left) { if (trueTwistTheta < 0.0f) { - ulnarCorrection -= glm::sign(ulnarDiff) * (fabs(ulnarDiff) / PI) * 40.0f * twistCoefficient; + ulnarCorrection -= glm::sign(ulnarDiff) * (fabsf(ulnarDiff) / PI) * 40.0f * twistCoefficient; } else { - ulnarCorrection += glm::sign(ulnarDiff) * (fabs(ulnarDiff) / PI) * 40.0f * twistCoefficient; + ulnarCorrection += glm::sign(ulnarDiff) * (fabsf(ulnarDiff) / PI) * 40.0f * twistCoefficient; } } else { // right hand if (trueTwistTheta > 0.0f) { - ulnarCorrection -= glm::sign(ulnarDiff) * (fabs(ulnarDiff) / PI) * 40.0f * twistCoefficient; + ulnarCorrection -= glm::sign(ulnarDiff) * (fabsf(ulnarDiff) / PI) * 40.0f * twistCoefficient; } else { - ulnarCorrection += glm::sign(ulnarDiff) * (fabs(ulnarDiff) / PI) * 40.0f * twistCoefficient; + ulnarCorrection += glm::sign(ulnarDiff) * (fabsf(ulnarDiff) / PI) * 40.0f * twistCoefficient; } } if (fabsf(ulnarCorrection) > 20.0f) { @@ -1998,15 +1997,12 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s float yValue = -1.0f * cos(thetaRadians); float zValue = 0.0f; glm::vec3 thetaVector(xValue, yValue, zValue); - //glm::vec3 thetaVector(1.0f, 0.0f, 0.0f); - glm::vec3 xAxis = glm::cross(Vectors::UNIT_Y, armToHand); - glm::vec3 up = glm::cross(armToHand, xAxis); - glm::quat armAxisRotation; - glm::vec3 u, v, w; + glm::vec3 up = Vectors::UNIT_Y; glm::vec3 fwd = armToHand/glm::length(armToHand); + glm::vec3 u, v, w; - generateBasisVectors(fwd, Vectors::UNIT_Y, u, v, w); + generateBasisVectors(fwd, up, u, v, w); AnimPose armAxisPose(glm::mat4(glm::vec4(-w, 0.0f), glm::vec4(v, 0.0f), glm::vec4(u, 0.0f), glm::vec4(glm::vec3(0.0f, 0.0f, 0.0f), 1.0f))); poleVector = armAxisPose * thetaVector; @@ -2092,9 +2088,6 @@ bool Rig::calculateElbowPoleVector(int handIndex, int elbowIndex, int armIndex, } poleVector = glm::normalize(attenuationVector + fullPoleVector + correctionVector); - if (handIndex == _animSkeleton->nameToJointIndex("LeftHand")) { - qCDebug(animation) << "the pole vector is " << poleVector; - } return true; } diff --git a/libraries/animation/src/Rig.h b/libraries/animation/src/Rig.h index 693aa732fa..94f18d789a 100644 --- a/libraries/animation/src/Rig.h +++ b/libraries/animation/src/Rig.h @@ -415,12 +415,6 @@ protected: glm::vec3 _prevLeftFootPoleVector { Vectors::UNIT_Z }; // sensor space bool _prevLeftFootPoleVectorValid { false }; - glm::vec3 _prevRightHandPoleVector { Vectors::UNIT_Z }; // sensor space - bool _prevRightHandPoleVectorValid { false }; - - glm::vec3 _prevLeftHandPoleVector { Vectors::UNIT_Z }; // sensor space - bool _prevLeftHandPoleVectorValid { false }; - int _rigId; bool _headEnabled { false }; bool _computeNetworkAnimation { false }; @@ -429,7 +423,7 @@ protected: float _twistThetaRunningAverageLeft { 0.0f }; float _flexThetaRunningAverageLeft { 0.0f }; float _ulnarRadialThetaRunningAverageLeft { 0.0f }; - float _twistThetaRunningAverageRight{ 0.0f }; + float _twistThetaRunningAverageRight { 0.0f }; float _flexThetaRunningAverageRight { 0.0f }; float _ulnarRadialThetaRunningAverageRight { 0.0f }; float _lastThetaLeft { 0.0f }; From 748368bfdac72aac4d900ff430eb686d2419d483 Mon Sep 17 00:00:00 2001 From: Angus Antley Date: Sun, 17 Feb 2019 23:32:52 -0800 Subject: [PATCH 087/112] mid tweak on the wrist and position coeffs --- interface/src/avatar/MySkeletonModel.cpp | 7 +- .../src/AnimPoleVectorConstraint.cpp | 2 + libraries/animation/src/Rig.cpp | 71 ++++++++++--------- 3 files changed, 46 insertions(+), 34 deletions(-) diff --git a/interface/src/avatar/MySkeletonModel.cpp b/interface/src/avatar/MySkeletonModel.cpp index 51a2c3767b..32a8e1e38d 100755 --- a/interface/src/avatar/MySkeletonModel.cpp +++ b/interface/src/avatar/MySkeletonModel.cpp @@ -15,6 +15,8 @@ #include "InterfaceLogging.h" #include "AnimUtil.h" +#define USE_Q_OS_ANDROID + MySkeletonModel::MySkeletonModel(Avatar* owningAvatar, QObject* parent) : SkeletonModel(owningAvatar, parent) { } @@ -250,8 +252,9 @@ void MySkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) { AnimPose headAvatarSpace(avatarHeadPose.getRotation(), avatarHeadPose.getTranslation()); AnimPose headRigSpace = avatarToRigPose * headAvatarSpace; AnimPose hipsRigSpace = sensorToRigPose * sensorHips; +#if defined(Q_OS_ANDROID) || defined(USE_Q_OS_ANDROID) glm::vec3 spine2TargetTranslation = computeSpine2WithHeadHipsSpline(myAvatar, hipsRigSpace, headRigSpace); - +#endif const float SPINE2_ROTATION_FILTER = 0.5f; AnimPose currentSpine2Pose; AnimPose currentHeadPose; @@ -273,7 +276,9 @@ void MySkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) { } generateBasisVectors(up, fwd, u, v, w); AnimPose newSpinePose(glm::mat4(glm::vec4(w, 0.0f), glm::vec4(u, 0.0f), glm::vec4(v, 0.0f), glm::vec4(glm::vec3(0.0f, 0.0f, 0.0f), 1.0f))); +#if defined(Q_OS_ANDROID) || defined(USE_Q_OS_ANDROID) currentSpine2Pose.trans() = spine2TargetTranslation; +#endif currentSpine2Pose.rot() = safeLerp(currentSpine2Pose.rot(), newSpinePose.rot(), SPINE2_ROTATION_FILTER); params.primaryControllerPoses[Rig::PrimaryControllerType_Spine2] = currentSpine2Pose; params.primaryControllerFlags[Rig::PrimaryControllerType_Spine2] = (uint8_t)Rig::ControllerFlags::Enabled | (uint8_t)Rig::ControllerFlags::Estimated; diff --git a/libraries/animation/src/AnimPoleVectorConstraint.cpp b/libraries/animation/src/AnimPoleVectorConstraint.cpp index f017fe2348..3745b1ab1f 100644 --- a/libraries/animation/src/AnimPoleVectorConstraint.cpp +++ b/libraries/animation/src/AnimPoleVectorConstraint.cpp @@ -123,6 +123,8 @@ const AnimPoseVec& AnimPoleVectorConstraint::evaluate(const AnimVariantMap& anim glm::quat deltaRot = glm::angleAxis(theta, unitAxis); + //qCDebug(animation) << "anim ik theta " << (theta/PI)*180.0f; + // transform result back into parent relative frame. glm::quat relBaseRot = glm::inverse(baseParentPose.rot()) * deltaRot * basePose.rot(); ikChain.setRelativePoseAtJointIndex(_baseJointIndex, AnimPose(relBaseRot, underPoses[_baseJointIndex].trans())); diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index ee8daef668..a7c0e60700 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -1714,7 +1714,7 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s const glm::vec3 biases(0.0f, 135.0f, 0.0f); // weights const float zWeightBottom = -100.0f; - const glm::vec3 weights(-50.0f, 60.0f, 260.0f); + const glm::vec3 weights(-50.0f, 60.0f, 90.0f); glm::vec3 armToHand = handPose.trans() - shoulderPose.trans(); glm::vec3 unitAxis; float axisLength = glm::length(armToHand); @@ -1724,22 +1724,24 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s unitAxis = Vectors::UNIT_Y; } float yFactor = (fabsf(armToHand[1] / defaultArmLength) * weights[1]) + biases[1]; - + float zFactor; if (armToHand[1] > 0.0f) { - zFactor = weights[2] * glm::max(zStart - (armToHand[2] / defaultArmLength), 0.0f) * fabsf(armToHand[1] / defaultArmLength); + zFactor = weights[2] * glm::max(zStart - (armToHand[2] / defaultArmLength), 0.0f) * glm::max(fabsf((armToHand[1] - 0.1f) / defaultArmLength), 0.0f); } else { zFactor = zWeightBottom * glm::max(zStart - (armToHand[2] / defaultArmLength), 0.0f) * fabsf(armToHand[1] / defaultArmLength); } float xFactor; if (left) { - xFactor = weights[0] * glm::max(-1.0f * (armToHand[0] / defaultArmLength) + xStart, 0.0f); + //xFactor = weights[0] * glm::max(-1.0f * (armToHand[0] / defaultArmLength) + xStart, 0.0f); + xFactor = weights[0] * ((-1.0f * (armToHand[0] / defaultArmLength) + xStart) - (0.2f) * ((1.0f + (armToHand[1] / defaultArmLength)) / 2.0f)); } else { - xFactor = weights[0] * (((armToHand[0] / defaultArmLength) + xStart) - (0.3f) * ((1.0f + (armToHand[1] / defaultArmLength)) / 2.0f)); + xFactor = weights[0] * (((armToHand[0] / defaultArmLength) + xStart) - (0.2f) * ((1.0f + (armToHand[1] / defaultArmLength)) / 2.0f)); } - + float theta = xFactor + yFactor + zFactor; + //float theta = yFactor; if (theta < 13.0f) { theta = 13.0f; @@ -1764,12 +1766,12 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s AnimPose updatedBase = shoulderPose * deltaRot; AnimPose newAbsMid = updatedBase * relMid; - + /* // now we calculate the contribution of the hand rotation relative to the arm // we are adding in the delta rotation so that we have the hand correction relative to the // latest theta for hand position - glm::quat relativeHandRotation = (newAbsMid.inverse() * handPose).rot(); - //glm::quat relativeHandRotation = (elbowPose.inverse() * handPose).rot(); + //glm::quat relativeHandRotation = (newAbsMid.inverse() * handPose).rot(); + glm::quat relativeHandRotation = (elbowPose.inverse() * handPose).rot(); if (relativeHandRotation.w < 0.0f) { relativeHandRotation *= -1.0f; } @@ -1795,9 +1797,9 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s ulnarDeviationTheta = -1.0f * ulnarDeviationTheta; } // put some smoothing on the theta - _ulnarRadialThetaRunningAverageRight = 0.5f * _ulnarRadialThetaRunningAverageRight + 0.5f * ulnarDeviationTheta; + _ulnarRadialThetaRunningAverageRight = 0.75f * _ulnarRadialThetaRunningAverageRight + 0.25f * ulnarDeviationTheta; } - + //get the flex/extension of the wrist rotation glm::quat flex; glm::quat nonFlex; @@ -1823,7 +1825,7 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s // put some smoothing on the theta _flexThetaRunningAverageRight = 0.5f * _flexThetaRunningAverageRight + 0.5f * flexTheta; } - + glm::quat twist; glm::quat nonTwist; swingTwistDecomposition(relativeHandRotation, Vectors::UNIT_Y, nonTwist, twist); @@ -1847,11 +1849,11 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s // put some smoothing on the theta _twistThetaRunningAverageRight = 0.5f * _twistThetaRunningAverageRight + 0.5f * trueTwistTheta; } - + if (!left) { - //qCDebug(animation) << "flex ave: " << (_flexThetaRunningAverageRight / PI) * 180.0f << " twist ave: " << (_twistThetaRunningAverageRight / PI) * 180.0f << " ulnar deviation ave: " << (_ulnarRadialThetaRunningAverageRight / PI) * 180.0f; + qCDebug(animation) << "flex ave: " << (_flexThetaRunningAverageRight / PI) * 180.0f << " twist ave: " << (_twistThetaRunningAverageRight / PI) * 180.0f << " ulnar deviation ave: " << (_ulnarRadialThetaRunningAverageRight / PI) * 180.0f; } - + const float FLEX_BOUNDARY = PI / 6.0f; const float EXTEND_BOUNDARY = -PI / 4.0f; float flexCorrection = 0.0f; @@ -1876,16 +1878,17 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s } theta -= flexCorrection; } + const float ULNAR_BOUNDARY_MINUS = -PI / 6.0f; - const float ULNAR_BOUNDARY_PLUS = PI / 6.0f; + const float ULNAR_BOUNDARY_PLUS = PI / 4.0f; float ulnarDiff = 0.0f; float ulnarCorrection = 0.0f; if (left) { - if (_ulnarRadialThetaRunningAverageLeft > ULNAR_BOUNDARY_PLUS) { - ulnarDiff = _ulnarRadialThetaRunningAverageLeft - ULNAR_BOUNDARY_PLUS; - } else if (_ulnarRadialThetaRunningAverageLeft < ULNAR_BOUNDARY_MINUS) { - ulnarDiff = _ulnarRadialThetaRunningAverageLeft - ULNAR_BOUNDARY_MINUS; + if (_ulnarRadialThetaRunningAverageLeft > -ULNAR_BOUNDARY_MINUS) { + ulnarDiff = _ulnarRadialThetaRunningAverageLeft + ULNAR_BOUNDARY_MINUS; + } else if (_ulnarRadialThetaRunningAverageLeft < -ULNAR_BOUNDARY_PLUS) { + ulnarDiff = _ulnarRadialThetaRunningAverageLeft + ULNAR_BOUNDARY_PLUS; } if (fabsf(ulnarDiff) > 0.0f) { float twistCoefficient = (fabsf(_twistThetaRunningAverageLeft) / (PI / 20.0f)); @@ -1893,17 +1896,17 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s twistCoefficient = 1.0f; } if (left) { - if (trueTwistTheta < 0.0f) { - ulnarCorrection -= glm::sign(ulnarDiff) * (fabsf(ulnarDiff) / PI) * 40.0f * twistCoefficient; + if (_twistThetaRunningAverageLeft < 0.0f) { + ulnarCorrection -= glm::sign(ulnarDiff) * (fabsf(ulnarDiff) / PI) * 80.0f * twistCoefficient; } else { - ulnarCorrection += glm::sign(ulnarDiff) * (fabsf(ulnarDiff) / PI) * 40.0f * twistCoefficient; + ulnarCorrection += glm::sign(ulnarDiff) * (fabsf(ulnarDiff) / PI) * 80.0f * twistCoefficient; } } else { // right hand - if (trueTwistTheta > 0.0f) { - ulnarCorrection -= glm::sign(ulnarDiff) * (fabsf(ulnarDiff) / PI) * 40.0f * twistCoefficient; + if (_twistThetaRunningAverageLeft > 0.0f) { + ulnarCorrection -= glm::sign(ulnarDiff) * (fabsf(ulnarDiff) / PI) * 80.0f * twistCoefficient; } else { - ulnarCorrection += glm::sign(ulnarDiff) * (fabsf(ulnarDiff) / PI) * 40.0f * twistCoefficient; + ulnarCorrection += glm::sign(ulnarDiff) * (fabsf(ulnarDiff) / PI) * 80.0f * twistCoefficient; } } if (fabsf(ulnarCorrection) > 20.0f) { @@ -1923,17 +1926,17 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s twistCoefficient = 1.0f; } if (left) { - if (trueTwistTheta < 0.0f) { - ulnarCorrection -= glm::sign(ulnarDiff) * (fabsf(ulnarDiff) / PI) * 40.0f * twistCoefficient; + if (_twistThetaRunningAverageRight < 0.0f) { + ulnarCorrection -= glm::sign(ulnarDiff) * (fabsf(ulnarDiff) / PI) * 80.0f * twistCoefficient; } else { - ulnarCorrection += glm::sign(ulnarDiff) * (fabsf(ulnarDiff) / PI) * 40.0f * twistCoefficient; + ulnarCorrection += glm::sign(ulnarDiff) * (fabsf(ulnarDiff) / PI) * 80.0f * twistCoefficient; } } else { // right hand - if (trueTwistTheta > 0.0f) { - ulnarCorrection -= glm::sign(ulnarDiff) * (fabsf(ulnarDiff) / PI) * 40.0f * twistCoefficient; + if (_twistThetaRunningAverageRight > 0.0f) { + ulnarCorrection -= glm::sign(ulnarDiff) * (fabsf(ulnarDiff) / PI) * 80.0f * twistCoefficient; } else { - ulnarCorrection += glm::sign(ulnarDiff) * (fabsf(ulnarDiff) / PI) * 40.0f * twistCoefficient; + ulnarCorrection += glm::sign(ulnarDiff) * (fabsf(ulnarDiff) / PI) * 80.0f * twistCoefficient; } } if (fabsf(ulnarCorrection) > 20.0f) { @@ -1943,6 +1946,7 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s } } + const float TWIST_DEADZONE = (4 * PI) / 9.0f; float twistCorrection = 0.0f; if (left) { @@ -1960,6 +1964,7 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s } else { theta += twistCorrection; } + */ // global limiting float thetaRadians = 0.0f; @@ -2007,7 +2012,7 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s poleVector = armAxisPose * thetaVector; if (left) { - qCDebug(animation) << "theta vector " << thetaVector; + //qCDebug(animation) << "theta vector " << thetaVector; //qCDebug(animation) << "fwd " << fwd; //qCDebug(animation) << "the x is " << w; //qCDebug(animation) << "the y is " << v; From f2301e7dac060eab7ade9fe59c813acca5911295 Mon Sep 17 00:00:00 2001 From: Angus Antley Date: Tue, 19 Feb 2019 07:35:13 -0800 Subject: [PATCH 088/112] fixed relative wrist correction problem --- .../src/AnimPoleVectorConstraint.cpp | 6 +- libraries/animation/src/Rig.cpp | 93 ++++++++----------- libraries/animation/src/Rig.h | 2 + 3 files changed, 45 insertions(+), 56 deletions(-) diff --git a/libraries/animation/src/AnimPoleVectorConstraint.cpp b/libraries/animation/src/AnimPoleVectorConstraint.cpp index 3745b1ab1f..afcf9b29ee 100644 --- a/libraries/animation/src/AnimPoleVectorConstraint.cpp +++ b/libraries/animation/src/AnimPoleVectorConstraint.cpp @@ -117,13 +117,15 @@ const AnimPoseVec& AnimPoleVectorConstraint::evaluate(const AnimVariantMap& anim if (axisLength > MIN_LENGTH && refVectorLength > MIN_LENGTH && sideVectorLength > MIN_LENGTH && refVectorProjLength > MIN_LENGTH && poleVectorProjLength > MIN_LENGTH) { - float dot = glm::clamp(glm::dot(refVectorProj / refVectorProjLength, poleVectorProj / poleVectorProjLength), 0.0f, 1.0f); + float dot = glm::clamp(glm::dot(refVectorProj / refVectorProjLength, poleVectorProj / poleVectorProjLength), -1.0f, 1.0f); float sideDot = glm::dot(poleVector, sideVector); float theta = copysignf(1.0f, sideDot) * acosf(dot); glm::quat deltaRot = glm::angleAxis(theta, unitAxis); - //qCDebug(animation) << "anim ik theta " << (theta/PI)*180.0f; + if (_tipJointName == "RightHand") { + qCDebug(animation) << "anim ik theta " << (theta / PI)*180.0f; + } // transform result back into parent relative frame. glm::quat relBaseRot = glm::inverse(baseParentPose.rot()) * deltaRot * basePose.rot(); diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index a7c0e60700..48ffdb4970 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -1723,8 +1723,9 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s } else { unitAxis = Vectors::UNIT_Y; } + float yFactor = (fabsf(armToHand[1] / defaultArmLength) * weights[1]) + biases[1]; - + float zFactor; if (armToHand[1] > 0.0f) { zFactor = weights[2] * glm::max(zStart - (armToHand[2] / defaultArmLength), 0.0f) * glm::max(fabsf((armToHand[1] - 0.1f) / defaultArmLength), 0.0f); @@ -1739,7 +1740,7 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s } else { xFactor = weights[0] * (((armToHand[0] / defaultArmLength) + xStart) - (0.2f) * ((1.0f + (armToHand[1] / defaultArmLength)) / 2.0f)); } - + float theta = xFactor + yFactor + zFactor; //float theta = yFactor; @@ -1766,7 +1767,7 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s AnimPose updatedBase = shoulderPose * deltaRot; AnimPose newAbsMid = updatedBase * relMid; - /* + // now we calculate the contribution of the hand rotation relative to the arm // we are adding in the delta rotation so that we have the hand correction relative to the // latest theta for hand position @@ -1799,7 +1800,7 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s // put some smoothing on the theta _ulnarRadialThetaRunningAverageRight = 0.75f * _ulnarRadialThetaRunningAverageRight + 0.25f * ulnarDeviationTheta; } - + //get the flex/extension of the wrist rotation glm::quat flex; glm::quat nonFlex; @@ -1825,7 +1826,7 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s // put some smoothing on the theta _flexThetaRunningAverageRight = 0.5f * _flexThetaRunningAverageRight + 0.5f * flexTheta; } - + glm::quat twist; glm::quat nonTwist; swingTwistDecomposition(relativeHandRotation, Vectors::UNIT_Y, nonTwist, twist); @@ -1849,13 +1850,11 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s // put some smoothing on the theta _twistThetaRunningAverageRight = 0.5f * _twistThetaRunningAverageRight + 0.5f * trueTwistTheta; } - - if (!left) { - qCDebug(animation) << "flex ave: " << (_flexThetaRunningAverageRight / PI) * 180.0f << " twist ave: " << (_twistThetaRunningAverageRight / PI) * 180.0f << " ulnar deviation ave: " << (_ulnarRadialThetaRunningAverageRight / PI) * 180.0f; - } - - const float FLEX_BOUNDARY = PI / 6.0f; - const float EXTEND_BOUNDARY = -PI / 4.0f; + + + float currentWristCoefficient = 0.0f; + const float FLEX_BOUNDARY = 0.0f; // PI / 6.0f; + const float EXTEND_BOUNDARY = 0.0f; //-PI / 4.0f; float flexCorrection = 0.0f; if (left) { if (_flexThetaRunningAverageLeft > FLEX_BOUNDARY) { @@ -1863,22 +1862,21 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s } else if (_flexThetaRunningAverageLeft < EXTEND_BOUNDARY) { flexCorrection = ((_flexThetaRunningAverageLeft - EXTEND_BOUNDARY) / PI) * 180.0f; } - if (fabsf(flexCorrection) > 30.0f) { - flexCorrection = glm::sign(flexCorrection) * 30.0f; + if (fabsf(flexCorrection) > 175.0f) { + flexCorrection = glm::sign(flexCorrection) * 175.0f; } - theta += flexCorrection; + currentWristCoefficient += flexCorrection; } else { if (_flexThetaRunningAverageRight > FLEX_BOUNDARY) { flexCorrection = ((_flexThetaRunningAverageRight - FLEX_BOUNDARY) / PI) * 180.0f; } else if (_flexThetaRunningAverageRight < EXTEND_BOUNDARY) { flexCorrection = ((_flexThetaRunningAverageRight - EXTEND_BOUNDARY) / PI) * 180.0f; } - if (fabsf(flexCorrection) > 30.0f) { - flexCorrection = glm::sign(flexCorrection) * 30.0f; + if (fabsf(flexCorrection) > 175.0f) { + flexCorrection = glm::sign(flexCorrection) * 175.0f; } - theta -= flexCorrection; + currentWristCoefficient -= flexCorrection; } - const float ULNAR_BOUNDARY_MINUS = -PI / 6.0f; const float ULNAR_BOUNDARY_PLUS = PI / 4.0f; @@ -1901,18 +1899,11 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s } else { ulnarCorrection += glm::sign(ulnarDiff) * (fabsf(ulnarDiff) / PI) * 80.0f * twistCoefficient; } - } else { - // right hand - if (_twistThetaRunningAverageLeft > 0.0f) { - ulnarCorrection -= glm::sign(ulnarDiff) * (fabsf(ulnarDiff) / PI) * 80.0f * twistCoefficient; - } else { - ulnarCorrection += glm::sign(ulnarDiff) * (fabsf(ulnarDiff) / PI) * 80.0f * twistCoefficient; - } } if (fabsf(ulnarCorrection) > 20.0f) { ulnarCorrection = glm::sign(ulnarCorrection) * 20.0f; } - theta += ulnarCorrection; + currentWristCoefficient += ulnarCorrection; } } else { if (_ulnarRadialThetaRunningAverageRight > ULNAR_BOUNDARY_PLUS) { @@ -1931,22 +1922,14 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s } else { ulnarCorrection += glm::sign(ulnarDiff) * (fabsf(ulnarDiff) / PI) * 80.0f * twistCoefficient; } - } else { - // right hand - if (_twistThetaRunningAverageRight > 0.0f) { - ulnarCorrection -= glm::sign(ulnarDiff) * (fabsf(ulnarDiff) / PI) * 80.0f * twistCoefficient; - } else { - ulnarCorrection += glm::sign(ulnarDiff) * (fabsf(ulnarDiff) / PI) * 80.0f * twistCoefficient; - } } if (fabsf(ulnarCorrection) > 20.0f) { ulnarCorrection = glm::sign(ulnarCorrection) * 20.0f; } - theta += ulnarCorrection; + currentWristCoefficient += ulnarCorrection; } } - const float TWIST_DEADZONE = (4 * PI) / 9.0f; float twistCorrection = 0.0f; if (left) { @@ -1960,11 +1943,24 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s } // limit the twist correction if (fabsf(twistCorrection) > 30.0f) { - theta += glm::sign(twistCorrection) * 30.0f; + currentWristCoefficient += glm::sign(twistCorrection) * 30.0f; } else { - theta += twistCorrection; + currentWristCoefficient += twistCorrection; + } + + if (left) { + _lastWristCoefficientLeft = _lastThetaLeft - theta; + _lastWristCoefficientLeft += currentWristCoefficient; + theta += _lastWristCoefficientLeft; + } else { + _lastWristCoefficientRight = _lastThetaRight - theta; + _lastWristCoefficientRight += currentWristCoefficient; + theta += _lastWristCoefficientRight; + } + + if (left) { + qCDebug(animation) << "theta " << theta << "Last wrist" << _lastWristCoefficientLeft << " flex ave: " << (_flexThetaRunningAverageLeft / PI) * 180.0f << " twist ave: " << (_twistThetaRunningAverageLeft / PI) * 180.0f << " ulnar deviation ave: " << (_ulnarRadialThetaRunningAverageLeft / PI) * 180.0f; } - */ // global limiting float thetaRadians = 0.0f; @@ -1973,9 +1969,7 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s _lastThetaLeft = 0.5f * _lastThetaLeft + 0.5f * theta; if (fabsf(_lastThetaLeft) < 50.0f) { - if (fabsf(_lastThetaLeft) < 50.0f) { - _lastThetaLeft = glm::sign(_lastThetaLeft) * 50.0f; - } + _lastThetaLeft = glm::sign(_lastThetaLeft) * 50.0f; } if (fabsf(_lastThetaLeft) > 175.0f) { _lastThetaLeft = glm::sign(_lastThetaLeft) * 175.0f; @@ -1986,10 +1980,9 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s // final global smoothing _lastThetaRight = 0.5f * _lastThetaRight + 0.5f * theta; - if (fabsf(_lastThetaRight) < 50.0f) { - if (fabsf(_lastThetaRight) < 50.0f) { - _lastThetaRight = glm::sign(_lastThetaRight) * 50.0f; - } + + if (fabsf(_lastThetaRight) < 10.0f) { + _lastThetaRight = glm::sign(_lastThetaRight) * 10.0f; } if (fabsf(_lastThetaRight) > 175.0f) { _lastThetaRight = glm::sign(_lastThetaRight) * 175.0f; @@ -2011,14 +2004,6 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s AnimPose armAxisPose(glm::mat4(glm::vec4(-w, 0.0f), glm::vec4(v, 0.0f), glm::vec4(u, 0.0f), glm::vec4(glm::vec3(0.0f, 0.0f, 0.0f), 1.0f))); poleVector = armAxisPose * thetaVector; - if (left) { - //qCDebug(animation) << "theta vector " << thetaVector; - //qCDebug(animation) << "fwd " << fwd; - //qCDebug(animation) << "the x is " << w; - //qCDebug(animation) << "the y is " << v; - //qCDebug(animation) << "the z is " << u; - } - return true; } diff --git a/libraries/animation/src/Rig.h b/libraries/animation/src/Rig.h index 94f18d789a..7b9c3d238d 100644 --- a/libraries/animation/src/Rig.h +++ b/libraries/animation/src/Rig.h @@ -428,6 +428,8 @@ protected: float _ulnarRadialThetaRunningAverageRight { 0.0f }; float _lastThetaLeft { 0.0f }; float _lastThetaRight { 0.0f }; + float _lastWristCoefficientRight { 0.0f }; + float _lastWristCoefficientLeft { 0.0f }; AnimContext _lastContext; AnimVariantMap _lastAnimVars; From 04e57d0dd1af9a90836c2b549f62f0bf8e0b10f7 Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Tue, 19 Feb 2019 17:45:46 -0700 Subject: [PATCH 089/112] No Rig pointer on Flow class, solve network animations and fixed bug --- interface/src/avatar/MyAvatar.cpp | 8 +- libraries/animation/src/Flow.cpp | 419 ++++++++++-------- libraries/animation/src/Flow.h | 87 +++- libraries/animation/src/Rig.cpp | 43 +- libraries/animation/src/Rig.h | 8 +- .../src/avatars-renderer/Avatar.cpp | 11 +- 6 files changed, 355 insertions(+), 221 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index f2e69ab5d3..f7c1052354 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -5317,15 +5317,17 @@ void MyAvatar::addAvatarHandsToFlow(const std::shared_ptr& otherAvatar) auto &flow = _skeletonModel->getRig().getFlow(); for (auto &handJointName : HAND_COLLISION_JOINTS) { int jointIndex = otherAvatar->getJointIndex(handJointName); - glm::vec3 position = otherAvatar->getJointPosition(jointIndex); - flow.setOthersCollision(otherAvatar->getID(), jointIndex, position); + if (jointIndex != -1) { + glm::vec3 position = otherAvatar->getJointPosition(jointIndex); + flow.setOthersCollision(otherAvatar->getID(), jointIndex, position); + } } } void MyAvatar::useFlow(bool isActive, bool isCollidable, const QVariantMap& physicsConfig, const QVariantMap& collisionsConfig) { if (_skeletonModel->isLoaded()) { + _skeletonModel->getRig().initFlow(isActive); auto &flow = _skeletonModel->getRig().getFlow(); - flow.init(isActive, isCollidable); auto &collisionSystem = flow.getCollisionSystem(); collisionSystem.setActive(isCollidable); auto physicsGroups = physicsConfig.keys(); diff --git a/libraries/animation/src/Flow.cpp b/libraries/animation/src/Flow.cpp index 974dd8dc54..86252b698d 100644 --- a/libraries/animation/src/Flow.cpp +++ b/libraries/animation/src/Flow.cpp @@ -197,7 +197,7 @@ void FlowNode::update(float deltaTime, const glm::vec3& accelerationOffset) { if (!_anchored) { // Add inertia const float FPS = 60.0f; - float timeRatio = (FPS * deltaTime); + float timeRatio = _scale * (FPS * deltaTime); float invertedTimeRatio = timeRatio > 0.0f ? 1.0f / timeRatio : 1.0f; auto deltaVelocity = _previousVelocity - _currentVelocity; auto centrifugeVector = glm::length(deltaVelocity) != 0.0f ? glm::normalize(deltaVelocity) : glm::vec3(); @@ -224,7 +224,7 @@ void FlowNode::solve(const glm::vec3& constrainPoint, float maxDistance, const F void FlowNode::solveConstraints(const glm::vec3& constrainPoint, float maxDistance) { glm::vec3 constrainVector = _currentPosition - constrainPoint; float difference = maxDistance / glm::length(constrainVector); - _currentPosition = difference < 1.0 ? constrainPoint + constrainVector * difference : _currentPosition; + _currentPosition = difference < 1.0f ? constrainPoint + constrainVector * difference : _currentPosition; }; void FlowNode::solveCollisions(const FlowCollisionResult& collision) { @@ -244,14 +244,13 @@ FlowJoint::FlowJoint(int jointIndex, int parentIndex, int childIndex, const QStr _group = group; _childIndex = childIndex; _parentIndex = parentIndex; - _node = FlowNode(glm::vec3(), settings); + FlowNode(glm::vec3(), settings); }; void FlowJoint::setInitialData(const glm::vec3& initialPosition, const glm::vec3& initialTranslation, const glm::quat& initialRotation, const glm::vec3& parentPosition) { _initialPosition = initialPosition; - _node._initialPosition = initialPosition; - _node._previousPosition = initialPosition; - _node._currentPosition = initialPosition; + _previousPosition = initialPosition; + _currentPosition = initialPosition; _initialTranslation = initialTranslation; _initialRotation = initialRotation; _translationDirection = glm::normalize(_initialTranslation); @@ -274,33 +273,48 @@ void FlowJoint::setRecoveryPosition(const glm::vec3& recoveryPosition) { void FlowJoint::update(float deltaTime) { glm::vec3 accelerationOffset = glm::vec3(0.0f); - if (_node._settings._stiffness > 0.0f) { - glm::vec3 recoveryVector = _recoveryPosition - _node._currentPosition; - float recoveryFactor = powf(_node._settings._stiffness, 3.0f); + if (_settings._stiffness > 0.0f) { + glm::vec3 recoveryVector = _recoveryPosition - _currentPosition; + float recoveryFactor = powf(_settings._stiffness, 3.0f); accelerationOffset = recoveryVector * recoveryFactor; } - _node.update(deltaTime, accelerationOffset); - if (_node._anchored) { + FlowNode::update(deltaTime, accelerationOffset); + if (_anchored) { if (!_isDummy) { - _node._currentPosition = _updatedPosition; + _currentPosition = _updatedPosition; } else { - _node._currentPosition = _parentPosition; + _currentPosition = _parentPosition; } } }; +void FlowJoint::setScale(float scale, bool initScale) { + if (initScale) { + _initialLength = _length / scale; + } + _settings._radius = _initialRadius * scale; + _length = _initialLength * scale; + _scale = scale; +} + void FlowJoint::solve(const FlowCollisionResult& collision) { - _node.solve(_parentPosition, _length, collision); + FlowNode::solve(_parentPosition, _length, collision); }; FlowDummyJoint::FlowDummyJoint(const glm::vec3& initialPosition, int index, int parentIndex, int childIndex, FlowPhysicsSettings settings) : FlowJoint(index, parentIndex, childIndex, DUMMY_KEYWORD + "_" + index, DUMMY_KEYWORD, settings) { _isDummy = true; _initialPosition = initialPosition; - _node = FlowNode(_initialPosition, settings); _length = DUMMY_JOINT_DISTANCE; } +void FlowDummyJoint::toIsolatedJoint(float length, int childIndex, const QString& group) { + _isDummy = false; + _length = length; + _childIndex = childIndex; + _group = group; + +} FlowThread::FlowThread(int rootIndex, std::map* joints) { _jointsPointer = joints; @@ -342,46 +356,38 @@ void FlowThread::computeFlowThread(int rootIndex) { void FlowThread::computeRecovery() { int parentIndex = _joints[0]; auto parentJoint = _jointsPointer->at(parentIndex); - _jointsPointer->at(parentIndex)._recoveryPosition = parentJoint._recoveryPosition = parentJoint._node._currentPosition; + _jointsPointer->at(parentIndex)._recoveryPosition = parentJoint._recoveryPosition = parentJoint._currentPosition; glm::quat parentRotation = parentJoint._parentWorldRotation * parentJoint._initialRotation; for (size_t i = 1; i < _joints.size(); i++) { auto joint = _jointsPointer->at(_joints[i]); - glm::quat rotation; - rotation = (i == 1) ? parentRotation : parentJoint._initialRotation; - _jointsPointer->at(_joints[i])._recoveryPosition = joint._recoveryPosition = parentJoint._recoveryPosition + (rotation * (joint._initialTranslation * 0.01f)); + _jointsPointer->at(_joints[i])._recoveryPosition = joint._recoveryPosition = parentJoint._recoveryPosition + (parentRotation * (joint._initialTranslation * 0.01f)); parentJoint = joint; } }; void FlowThread::update(float deltaTime) { - if (getActive()) { - _positions.clear(); - auto &firstJoint = _jointsPointer->at(_joints[0]); - _radius = firstJoint._node._settings._radius; - if (firstJoint._node._settings._stiffness > 0.0f) { - computeRecovery(); - } - for (size_t i = 0; i < _joints.size(); i++) { - auto &joint = _jointsPointer->at(_joints[i]); - joint.update(deltaTime); - _positions.push_back(joint._node._currentPosition); - } + _positions.clear(); + auto &firstJoint = _jointsPointer->at(_joints[0]); + _radius = firstJoint._settings._radius; + computeRecovery(); + for (size_t i = 0; i < _joints.size(); i++) { + auto &joint = _jointsPointer->at(_joints[i]); + joint.update(deltaTime); + _positions.push_back(joint._currentPosition); } }; void FlowThread::solve(FlowCollisionSystem& collisionSystem) { - if (getActive()) { - if (collisionSystem.getActive()) { - auto bodyCollisions = collisionSystem.checkFlowThreadCollisions(this); - for (size_t i = 0; i < _joints.size(); i++) { - int index = _joints[i]; - _jointsPointer->at(index).solve(bodyCollisions[i]); - } - } else { - for (size_t i = 0; i < _joints.size(); i++) { - int index = _joints[i]; - _jointsPointer->at(index).solve(FlowCollisionResult()); - } + if (collisionSystem.getActive()) { + auto bodyCollisions = collisionSystem.checkFlowThreadCollisions(this); + for (size_t i = 0; i < _joints.size(); i++) { + int index = _joints[i]; + _jointsPointer->at(index).solve(bodyCollisions[i]); + } + } else { + for (size_t i = 0; i < _joints.size(); i++) { + int index = _joints[i]; + _jointsPointer->at(index).solve(FlowCollisionResult()); } } }; @@ -421,94 +427,102 @@ void FlowThread::computeJointRotations() { joint0 = joint1; joint1 = nextJoint; } -}; - -void FlowThread::apply() { - if (!getActive()) { - return; - } - computeJointRotations(); -}; - -bool FlowThread::getActive() { - return _jointsPointer->at(_joints[0])._node._active; -}; - -void Flow::init(bool isActive, bool isCollidable) { - if (isActive) { - if (!_initialized) { - calculateConstraints(); - } - } else { - cleanUp(); - } - + } -void Flow::calculateConstraints() { +void FlowThread::setScale(float scale, bool initScale) { + for (size_t i = 0; i < _joints.size(); i++) { + auto &joint = _jointsPointer->at(_joints[i]); + joint.setScale(scale, initScale); + } + resetLength(); +} + +FlowThread& FlowThread::operator=(const FlowThread& otherFlowThread) { + for (int jointIndex: otherFlowThread._joints) { + auto& joint = otherFlowThread._jointsPointer->at(jointIndex); + auto& myJoint = _jointsPointer->at(jointIndex); + myJoint._acceleration = joint._acceleration; + myJoint._currentPosition = joint._currentPosition; + myJoint._currentRotation = joint._currentRotation; + myJoint._currentVelocity = joint._currentVelocity; + myJoint._length = joint._length; + myJoint._parentPosition = joint._parentPosition; + myJoint._parentWorldRotation = joint._parentWorldRotation; + myJoint._previousPosition = joint._previousPosition; + myJoint._previousVelocity = joint._previousVelocity; + myJoint._scale = joint._scale; + myJoint._translationDirection = joint._translationDirection; + myJoint._updatedPosition = joint._updatedPosition; + myJoint._updatedRotation = joint._updatedRotation; + myJoint._updatedTranslation = joint._updatedTranslation; + } + return *this; +} + +void Flow::calculateConstraints(const std::shared_ptr& skeleton, + AnimPoseVec& relativePoses, AnimPoseVec& absolutePoses) { cleanUp(); - if (!_rig) { + if (!skeleton) { return; } int rightHandIndex = -1; auto flowPrefix = FLOW_JOINT_PREFIX.toUpper(); auto simPrefix = SIM_JOINT_PREFIX.toUpper(); - auto skeleton = _rig->getAnimSkeleton(); std::vector handsIndices; - if (skeleton) { - for (int i = 0; i < skeleton->getNumJoints(); i++) { - auto name = skeleton->getJointName(i); - if (name == "RightHand") { - rightHandIndex = i; - } - if (std::find(HAND_COLLISION_JOINTS.begin(), HAND_COLLISION_JOINTS.end(), name) != HAND_COLLISION_JOINTS.end()) { - handsIndices.push_back(i); - } - auto parentIndex = skeleton->getParentIndex(i); - if (parentIndex == -1) { - continue; - } - auto jointChildren = skeleton->getChildrenOfJoint(i); - // auto childIndex = jointChildren.size() > 0 ? jointChildren[0] : -1; - auto group = QStringRef(&name, 0, 3).toString().toUpper(); - auto split = name.split("_"); - bool isSimJoint = (group == simPrefix); - bool isFlowJoint = split.size() > 2 && split[0].toUpper() == flowPrefix; - if (isFlowJoint || isSimJoint) { - group = ""; - if (isSimJoint) { - for (int j = 1; j < name.size() - 1; j++) { - bool toFloatSuccess; - QStringRef(&name, (int)(name.size() - j), 1).toString().toFloat(&toFloatSuccess); - if (!toFloatSuccess && (name.size() - j) > (int)simPrefix.size()) { - group = QStringRef(&name, (int)simPrefix.size(), (int)(name.size() - j + 1)).toString(); - break; - } - } - if (group.isEmpty()) { - group = QStringRef(&name, (int)simPrefix.size(), name.size() - 1).toString(); - } - qCDebug(animation) << "Sim joint added to flow: " << name; - } else { - group = split[1]; - } - if (!group.isEmpty()) { - _flowJointKeywords.push_back(group); - FlowPhysicsSettings jointSettings; - if (PRESET_FLOW_DATA.find(group) != PRESET_FLOW_DATA.end()) { - jointSettings = PRESET_FLOW_DATA.at(group); - } else { - jointSettings = DEFAULT_JOINT_SETTINGS; - } - if (_flowJointData.find(i) == _flowJointData.end()) { - auto flowJoint = FlowJoint(i, parentIndex, -1, name, group, jointSettings); - _flowJointData.insert(std::pair(i, flowJoint)); + + for (int i = 0; i < skeleton->getNumJoints(); i++) { + auto name = skeleton->getJointName(i); + if (name == "RightHand") { + rightHandIndex = i; + } + if (std::find(HAND_COLLISION_JOINTS.begin(), HAND_COLLISION_JOINTS.end(), name) != HAND_COLLISION_JOINTS.end()) { + handsIndices.push_back(i); + } + auto parentIndex = skeleton->getParentIndex(i); + if (parentIndex == -1) { + continue; + } + auto jointChildren = skeleton->getChildrenOfJoint(i); + // auto childIndex = jointChildren.size() > 0 ? jointChildren[0] : -1; + auto group = QStringRef(&name, 0, 3).toString().toUpper(); + auto split = name.split("_"); + bool isSimJoint = (group == simPrefix); + bool isFlowJoint = split.size() > 2 && split[0].toUpper() == flowPrefix; + if (isFlowJoint || isSimJoint) { + group = ""; + if (isSimJoint) { + for (int j = 1; j < name.size() - 1; j++) { + bool toFloatSuccess; + QStringRef(&name, (int)(name.size() - j), 1).toString().toFloat(&toFloatSuccess); + if (!toFloatSuccess && (name.size() - j) > (int)simPrefix.size()) { + group = QStringRef(&name, (int)simPrefix.size(), (int)(name.size() - j + 1)).toString(); + break; } } + if (group.isEmpty()) { + group = QStringRef(&name, (int)simPrefix.size(), name.size() - 1).toString(); + } + qCDebug(animation) << "Sim joint added to flow: " << name; } else { - if (PRESET_COLLISION_DATA.find(name) != PRESET_COLLISION_DATA.end()) { - _collisionSystem.addCollisionSphere(i, PRESET_COLLISION_DATA.at(name)); + group = split[1]; + } + if (!group.isEmpty()) { + _flowJointKeywords.push_back(group); + FlowPhysicsSettings jointSettings; + if (PRESET_FLOW_DATA.find(group) != PRESET_FLOW_DATA.end()) { + jointSettings = PRESET_FLOW_DATA.at(group); + } else { + jointSettings = DEFAULT_JOINT_SETTINGS; } + if (_flowJointData.find(i) == _flowJointData.end()) { + auto flowJoint = FlowJoint(i, parentIndex, -1, name, group, jointSettings); + _flowJointData.insert(std::pair(i, flowJoint)); + } + } + } else { + if (PRESET_COLLISION_DATA.find(name) != PRESET_COLLISION_DATA.end()) { + _collisionSystem.addCollisionSphere(i, PRESET_COLLISION_DATA.at(name)); } } } @@ -517,10 +531,10 @@ void Flow::calculateConstraints() { int jointIndex = jointData.first; glm::vec3 jointPosition, parentPosition, jointTranslation; glm::quat jointRotation; - _rig->getJointPositionInWorldFrame(jointIndex, jointPosition, _entityPosition, _entityRotation); - _rig->getJointPositionInWorldFrame(jointData.second._parentIndex, parentPosition, _entityPosition, _entityRotation); - _rig->getJointTranslation(jointIndex, jointTranslation); - _rig->getJointRotation(jointIndex, jointRotation); + getJointPositionInWorldFrame(absolutePoses, jointIndex, jointPosition, _entityPosition, _entityRotation); + getJointPositionInWorldFrame(absolutePoses, jointData.second.getParentIndex(), parentPosition, _entityPosition, _entityRotation); + getJointTranslation(relativePoses, jointIndex, jointTranslation); + getJointRotation(relativePoses, jointIndex, jointRotation); jointData.second.setInitialData(jointPosition, jointTranslation, jointRotation, parentPosition); } @@ -528,11 +542,11 @@ void Flow::calculateConstraints() { std::vector roots; for (auto &joint :_flowJointData) { - if (_flowJointData.find(joint.second._parentIndex) == _flowJointData.end()) { - joint.second._node._anchored = true; + if (_flowJointData.find(joint.second.getParentIndex()) == _flowJointData.end()) { + joint.second.setAnchored(true); roots.push_back(joint.first); } else { - _flowJointData[joint.second._parentIndex]._childIndex = joint.first; + _flowJointData[joint.second.getParentIndex()].setChildIndex(joint.first); } } @@ -543,15 +557,12 @@ void Flow::calculateConstraints() { if (thread._joints.size() == 1) { int jointIndex = roots[i]; auto joint = _flowJointData[jointIndex]; - auto jointPosition = joint._updatedPosition; - auto newSettings = FlowPhysicsSettings(joint._node._settings); + auto jointPosition = joint.getUpdatedPosition(); + auto newSettings = FlowPhysicsSettings(joint.getSettings()); newSettings._stiffness = ISOLATED_JOINT_STIFFNESS; int extraIndex = (int)_flowJointData.size(); auto newJoint = FlowDummyJoint(jointPosition, extraIndex, jointIndex, -1, newSettings); - newJoint._isDummy = false; - newJoint._length = ISOLATED_JOINT_LENGTH; - newJoint._childIndex = extraIndex; - newJoint._group = _flowJointData[jointIndex]._group; + newJoint.toIsolatedJoint(ISOLATED_JOINT_LENGTH, extraIndex, _flowJointData[jointIndex].getGroup()); thread = FlowThread(jointIndex, &_flowJointData); } _jointThreads.push_back(thread); @@ -559,13 +570,13 @@ void Flow::calculateConstraints() { } if (_jointThreads.size() == 0) { - _rig->clearJointStates(); + onCleanup(); } if (SHOW_DUMMY_JOINTS && rightHandIndex > -1) { int jointCount = (int)_flowJointData.size(); int extraIndex = (int)_flowJointData.size(); glm::vec3 rightHandPosition; - _rig->getJointPositionInWorldFrame(rightHandIndex, rightHandPosition, _entityPosition, _entityRotation); + getJointPositionInWorldFrame(absolutePoses, rightHandIndex, rightHandPosition, _entityPosition, _entityRotation); int parentIndex = rightHandIndex; for (int i = 0; i < DUMMY_JOINT_COUNT; i++) { int childIndex = (i == (DUMMY_JOINT_COUNT - 1)) ? -1 : extraIndex + 1; @@ -574,7 +585,7 @@ void Flow::calculateConstraints() { parentIndex = extraIndex; extraIndex++; } - _flowJointData[jointCount]._node._anchored = true; + _flowJointData[jointCount].setAnchored(true); auto extraThread = FlowThread(jointCount, &_flowJointData); _jointThreads.push_back(extraThread); @@ -596,70 +607,70 @@ void Flow::cleanUp() { _collisionSystem.resetCollisions(); _initialized = false; _isScaleSet = false; - _active = false; - if (_rig) { - _rig->clearJointStates(); - } - + onCleanup(); } void Flow::setTransform(float scale, const glm::vec3& position, const glm::quat& rotation) { _scale = scale; _entityPosition = position; _entityRotation = rotation; - _active = _initialized; } void Flow::setScale(float scale) { - if (!_isScaleSet) { - for (auto &joint : _flowJointData) { - joint.second._initialLength = joint.second._length / _scale; - } - _isScaleSet = true; - } - _lastScale = _scale; _collisionSystem.setScale(_scale); for (size_t i = 0; i < _jointThreads.size(); i++) { - for (size_t j = 0; j < _jointThreads[i]._joints.size(); j++) { - auto &joint = _flowJointData[_jointThreads[i]._joints[j]]; - joint._node._settings._radius = joint._node._initialRadius * _scale; - joint._length = joint._initialLength * _scale; - } - _jointThreads[i].resetLength(); + _jointThreads[i].setScale(_scale, !_isScaleSet); } + if (_lastScale != _scale) { + _lastScale = _scale; + _isScaleSet = true; + } + } -void Flow::update(float deltaTime) { +void Flow::update(float deltaTime, AnimPoseVec& relativePoses, AnimPoseVec& absolutePoses, const std::vector& overrideFlags) { if (_initialized && _active) { uint64_t startTime = usecTimestampNow(); uint64_t updateExpiry = startTime + MAX_UPDATE_FLOW_TIME_BUDGET; if (_scale != _lastScale) { setScale(_scale); } - updateJoints(); for (size_t i = 0; i < _jointThreads.size(); i++) { size_t index = _invertThreadLoop ? _jointThreads.size() - 1 - i : i; auto &thread = _jointThreads[index]; thread.update(deltaTime); thread.solve(_collisionSystem); - if (!updateRootFramePositions(index)) { + if (!updateRootFramePositions(absolutePoses, index)) { return; } - thread.apply(); + thread.computeJointRotations(); if (usecTimestampNow() > updateExpiry) { break; - qWarning(animation) << "Flow Bones ran out of time updating threads"; + qWarning(animation) << "Flow Bones ran out of time while updating threads"; } } - setJoints(); + setJoints(relativePoses, overrideFlags); + updateJoints(relativePoses, absolutePoses); _invertThreadLoop = !_invertThreadLoop; } } -bool Flow::worldToJointPoint(const glm::vec3& position, const int jointIndex, glm::vec3& jointSpacePosition) const { +void Flow::updateAbsolutePoses(const AnimPoseVec& relativePoses, AnimPoseVec& absolutePoses) { + for (auto &joint : _flowJointData) { + int index = joint.second.getIndex(); + int parentIndex = joint.second.getParentIndex(); + if (index >= 0 && index < relativePoses.size() && + parentIndex >= 0 && parentIndex < absolutePoses.size()) { + absolutePoses[index] = absolutePoses[parentIndex] * relativePoses[index]; + } + } +} + +bool Flow::worldToJointPoint(const AnimPoseVec& absolutePoses, const glm::vec3& position, const int jointIndex, glm::vec3& jointSpacePosition) const { glm::vec3 jointPos; glm::quat jointRot; - if (_rig->getJointPositionInWorldFrame(jointIndex, jointPos, _entityPosition, _entityRotation) && _rig->getJointRotationInWorldFrame(jointIndex, jointRot, _entityRotation)) { + if (getJointPositionInWorldFrame(absolutePoses, jointIndex, jointPos, _entityPosition, _entityRotation) && + getJointRotationInWorldFrame(absolutePoses, jointIndex, jointRot, _entityRotation)) { glm::vec3 modelOffset = position - jointPos; jointSpacePosition = glm::inverse(jointRot) * modelOffset; return true; @@ -667,13 +678,13 @@ bool Flow::worldToJointPoint(const glm::vec3& position, const int jointIndex, gl return false; } -bool Flow::updateRootFramePositions(size_t threadIndex) { +bool Flow::updateRootFramePositions(const AnimPoseVec& absolutePoses, size_t threadIndex) { auto &joints = _jointThreads[threadIndex]._joints; - int rootIndex = _flowJointData[joints[0]]._parentIndex; + int rootIndex = _flowJointData[joints[0]].getParentIndex(); _jointThreads[threadIndex]._rootFramePositions.clear(); for (size_t j = 0; j < joints.size(); j++) { glm::vec3 jointPos; - if (worldToJointPoint(_flowJointData[joints[j]]._node._currentPosition, rootIndex, jointPos)) { + if (worldToJointPoint(absolutePoses, _flowJointData[joints[j]].getCurrentPosition(), rootIndex, jointPos)) { _jointThreads[threadIndex]._rootFramePositions.push_back(jointPos); } else { return false; @@ -682,35 +693,38 @@ bool Flow::updateRootFramePositions(size_t threadIndex) { return true; } -void Flow::updateJoints() { +void Flow::updateJoints(AnimPoseVec& relativePoses, AnimPoseVec& absolutePoses) { + updateAbsolutePoses(relativePoses, absolutePoses); for (auto &jointData : _flowJointData) { int jointIndex = jointData.first; glm::vec3 jointPosition, parentPosition, jointTranslation; glm::quat jointRotation, parentWorldRotation; - _rig->getJointPositionInWorldFrame(jointIndex, jointPosition, _entityPosition, _entityRotation); - _rig->getJointPositionInWorldFrame(jointData.second._parentIndex, parentPosition, _entityPosition, _entityRotation); - _rig->getJointTranslation(jointIndex, jointTranslation); - _rig->getJointRotation(jointIndex, jointRotation); - _rig->getJointRotationInWorldFrame(jointData.second._parentIndex, parentWorldRotation, _entityRotation); + getJointPositionInWorldFrame(absolutePoses, jointIndex, jointPosition, _entityPosition, _entityRotation); + getJointPositionInWorldFrame(absolutePoses, jointData.second.getParentIndex(), parentPosition, _entityPosition, _entityRotation); + getJointTranslation(relativePoses, jointIndex, jointTranslation); + getJointRotation(relativePoses, jointIndex, jointRotation); + getJointRotationInWorldFrame(absolutePoses, jointData.second.getParentIndex(), parentWorldRotation, _entityRotation); jointData.second.setUpdatedData(jointPosition, jointTranslation, jointRotation, parentPosition, parentWorldRotation); } auto &selfCollisions = _collisionSystem.getSelfCollisions(); for (auto &collision : selfCollisions) { glm::quat jointRotation; - _rig->getJointPositionInWorldFrame(collision._jointIndex, collision._position, _entityPosition, _entityRotation); - _rig->getJointRotationInWorldFrame(collision._jointIndex, jointRotation, _entityRotation); + getJointPositionInWorldFrame(absolutePoses, collision._jointIndex, collision._position, _entityPosition, _entityRotation); + getJointRotationInWorldFrame(absolutePoses, collision._jointIndex, jointRotation, _entityRotation); glm::vec3 worldOffset = jointRotation * collision._offset; collision._position = collision._position + worldOffset; } _collisionSystem.prepareCollisions(); } -void Flow::setJoints() { +void Flow::setJoints(AnimPoseVec& relativePoses, const std::vector& overrideFlags) { for (auto &thread : _jointThreads) { auto &joints = thread._joints; for (int jointIndex : joints) { auto &joint = _flowJointData[jointIndex]; - _rig->setJointRotation(jointIndex, true, joint._currentRotation, 2.0f); + if (jointIndex >= 0 && jointIndex < (int)relativePoses.size() && !overrideFlags[jointIndex]) { + relativePoses[jointIndex].rot() = joint.getCurrentRotation(); + } } } } @@ -724,8 +738,61 @@ void Flow::setOthersCollision(const QUuid& otherId, int jointIndex, const glm::v void Flow::setPhysicsSettingsForGroup(const QString& group, const FlowPhysicsSettings& settings) { for (auto &joint : _flowJointData) { - if (joint.second._group.toUpper() == group.toUpper()) { - joint.second._node._settings = settings; + if (joint.second.getGroup().toUpper() == group.toUpper()) { + joint.second.setSettings(settings); } } +} + +bool Flow::getJointPositionInWorldFrame(const AnimPoseVec& absolutePoses, int jointIndex, glm::vec3& position, glm::vec3 translation, glm::quat rotation) const { + if (jointIndex >= 0 && jointIndex < (int)absolutePoses.size()) { + glm::vec3 poseSetTrans = absolutePoses[jointIndex].trans(); + position = (rotation * poseSetTrans) + translation; + if (!isNaN(position)) { + return true; + } else { + position = glm::vec3(0.0f); + } + } + return false; +} + +bool Flow::getJointRotationInWorldFrame(const AnimPoseVec& absolutePoses, int jointIndex, glm::quat& result, const glm::quat& rotation) const { + if (jointIndex >= 0 && jointIndex < (int)absolutePoses.size()) { + result = rotation * absolutePoses[jointIndex].rot(); + return true; + } else { + return false; + } +} + +bool Flow::getJointRotation(const AnimPoseVec& relativePoses, int jointIndex, glm::quat& rotation) const { + if (jointIndex >= 0 && jointIndex < (int)relativePoses.size()) { + rotation = relativePoses[jointIndex].rot(); + return true; + } else { + return false; + } +} + +bool Flow::getJointTranslation(const AnimPoseVec& relativePoses, int jointIndex, glm::vec3& translation) const { + if (jointIndex >= 0 && jointIndex < (int)relativePoses.size()) { + translation = relativePoses[jointIndex].trans(); + return true; + } else { + return false; + } +} + +Flow& Flow::operator=(const Flow& otherFlow) { + _active = otherFlow.getActive(); + _scale = otherFlow.getScale(); + _isScaleSet = true; + auto &threads = otherFlow.getThreads(); + if (threads.size() == _jointThreads.size()) { + for (size_t i = 0; i < _jointThreads.size(); i++) { + _jointThreads[i] = threads[i]; + } + } + return *this; } \ No newline at end of file diff --git a/libraries/animation/src/Flow.h b/libraries/animation/src/Flow.h index bb15846b5e..e3e20e25f9 100644 --- a/libraries/animation/src/Flow.h +++ b/libraries/animation/src/Flow.h @@ -17,6 +17,7 @@ #include #include #include +#include "AnimPose.h" class Rig; class AnimSkeleton; @@ -175,6 +176,13 @@ class FlowNode { public: FlowNode() {}; FlowNode(const glm::vec3& initialPosition, FlowPhysicsSettings settings); + + void update(float deltaTime, const glm::vec3& accelerationOffset); + void solve(const glm::vec3& constrainPoint, float maxDistance, const FlowCollisionResult& collision); + void solveConstraints(const glm::vec3& constrainPoint, float maxDistance); + void solveCollisions(const FlowCollisionResult& collision); + +protected: FlowPhysicsSettings _settings; glm::vec3 _initialPosition; @@ -194,15 +202,14 @@ public: bool _colliding { false }; bool _active { true }; - void update(float deltaTime, const glm::vec3& accelerationOffset); - void solve(const glm::vec3& constrainPoint, float maxDistance, const FlowCollisionResult& collision); - void solveConstraints(const glm::vec3& constrainPoint, float maxDistance); - void solveCollisions(const FlowCollisionResult& collision); + float _scale{ 1.0f }; }; -class FlowJoint { +class FlowJoint : public FlowNode { public: - FlowJoint() {}; + friend class FlowThread; + + FlowJoint(): FlowNode() {}; FlowJoint(int jointIndex, int parentIndex, int childIndex, const QString& name, const QString& group, const FlowPhysicsSettings& settings); void setInitialData(const glm::vec3& initialPosition, const glm::vec3& initialTranslation, const glm::quat& initialRotation, const glm::vec3& parentPosition); void setUpdatedData(const glm::vec3& updatedPosition, const glm::vec3& updatedTranslation, const glm::quat& updatedRotation, const glm::vec3& parentPosition, const glm::quat& parentWorldRotation); @@ -210,13 +217,30 @@ public: void update(float deltaTime); void solve(const FlowCollisionResult& collision); + void setScale(float scale, bool initScale); + bool isAnchored() { return _anchored; } + void setAnchored(bool anchored) { _anchored = anchored; } + + const FlowPhysicsSettings& getSettings() { return _settings; } + void setSettings(const FlowPhysicsSettings& settings) { _settings = settings; } + + const glm::vec3& getCurrentPosition() { return _currentPosition; } + int getIndex() { return _index; } + int getParentIndex() { return _parentIndex; } + void setChildIndex(int index) { _childIndex = index; } + const glm::vec3& getUpdatedPosition() { return _updatedPosition; } + const QString& getGroup() { return _group; } + const glm::quat& getCurrentRotation() { return _currentRotation; } + +protected: + int _index{ -1 }; int _parentIndex{ -1 }; int _childIndex{ -1 }; QString _name; QString _group; bool _isDummy{ false }; - glm::vec3 _initialPosition; + glm::vec3 _initialTranslation; glm::quat _initialRotation; @@ -229,24 +253,26 @@ public: glm::vec3 _parentPosition; glm::quat _parentWorldRotation; - - FlowNode _node; glm::vec3 _translationDirection; - float _scale { 1.0f }; + float _length { 0.0f }; float _initialLength { 0.0f }; + bool _applyRecovery { false }; }; class FlowDummyJoint : public FlowJoint { public: FlowDummyJoint(const glm::vec3& initialPosition, int index, int parentIndex, int childIndex, FlowPhysicsSettings settings); + void toIsolatedJoint(float length, int childIndex, const QString& group); }; class FlowThread { public: FlowThread() {}; + FlowThread& operator=(const FlowThread& otherFlowThread); + FlowThread(int rootIndex, std::map* joints); void resetLength(); @@ -255,9 +281,8 @@ public: void update(float deltaTime); void solve(FlowCollisionSystem& collisionSystem); void computeJointRotations(); - void apply(); - bool getActive(); void setRootFramePositions(const std::vector& rootFramePositions) { _rootFramePositions = rootFramePositions; } + void setScale(float scale, bool initScale = false); std::vector _joints; std::vector _positions; @@ -267,27 +292,41 @@ public: std::vector _rootFramePositions; }; -class Flow { +class Flow : public QObject{ + Q_OBJECT public: - Flow(Rig* rig) { _rig = rig; }; - void init(bool isActive, bool isCollidable); - bool isActive() { return _active; } - void calculateConstraints(); - void update(float deltaTime); + Flow() { } + Flow& operator=(const Flow& otherFlow); + bool getActive() const { return _active; } + void setActive(bool active) { _active = active; } + bool isInitialized() const { return _initialized; } + float getScale() const { return _scale; } + void calculateConstraints(const std::shared_ptr& skeleton, AnimPoseVec& relativePoses, AnimPoseVec& absolutePoses); + void update(float deltaTime, AnimPoseVec& relativePoses, AnimPoseVec& absolutePoses, const std::vector& overrideFlags); void setTransform(float scale, const glm::vec3& position, const glm::quat& rotation); const std::map& getJoints() const { return _flowJointData; } const std::vector& getThreads() const { return _jointThreads; } void setOthersCollision(const QUuid& otherId, int jointIndex, const glm::vec3& position); FlowCollisionSystem& getCollisionSystem() { return _collisionSystem; } void setPhysicsSettingsForGroup(const QString& group, const FlowPhysicsSettings& settings); -private: - void setJoints(); void cleanUp(); - void updateJoints(); - bool updateRootFramePositions(size_t threadIndex); - bool worldToJointPoint(const glm::vec3& position, const int jointIndex, glm::vec3& jointSpacePosition) const; + +signals: + void onCleanup(); + +private: + void updateAbsolutePoses(const AnimPoseVec& relativePoses, AnimPoseVec& absolutePoses); + bool getJointPositionInWorldFrame(const AnimPoseVec& absolutePoses, int jointIndex, glm::vec3& position, glm::vec3 translation, glm::quat rotation) const; + bool getJointRotationInWorldFrame(const AnimPoseVec& absolutePoses, int jointIndex, glm::quat& result, const glm::quat& rotation) const; + bool getJointRotation(const AnimPoseVec& relativePoses, int jointIndex, glm::quat& rotation) const; + bool getJointTranslation(const AnimPoseVec& relativePoses, int jointIndex, glm::vec3& translation) const; + bool worldToJointPoint(const AnimPoseVec& absolutePoses, const glm::vec3& position, const int jointIndex, glm::vec3& jointSpacePosition) const; + + void setJoints(AnimPoseVec& relativePoses, const std::vector& overrideFlags); + void updateJoints(AnimPoseVec& relativePoses, AnimPoseVec& absolutePoses); + bool updateRootFramePositions(const AnimPoseVec& absolutePoses, size_t threadIndex); void setScale(float scale); - Rig* _rig; + float _scale { 1.0f }; float _lastScale{ 1.0f }; glm::vec3 _entityPosition; diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index 8cc5fcc337..eb02f07e62 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -74,7 +74,7 @@ static const QString MAIN_STATE_MACHINE_RIGHT_FOOT_ROTATION("mainStateMachineRig static const QString MAIN_STATE_MACHINE_RIGHT_FOOT_POSITION("mainStateMachineRightFootPosition"); -Rig::Rig() : _flow(this) { +Rig::Rig() { // Ensure thread-safe access to the rigRegistry. std::lock_guard guard(rigRegistryMutex); @@ -361,7 +361,6 @@ void Rig::reset(const HFMModel& hfmModel) { _animSkeleton = std::make_shared(hfmModel); - _internalPoseSet._relativePoses.clear(); _internalPoseSet._relativePoses = _animSkeleton->getRelativeDefaultPoses(); @@ -745,7 +744,8 @@ void Rig::computeMotionAnimationState(float deltaTime, const glm::vec3& worldPos glm::vec3 forward = worldRotation * IDENTITY_FORWARD; glm::vec3 workingVelocity = worldVelocity; - _flow.setTransform(sensorToWorldScale, worldPosition, worldRotation * Quaternions::Y_180); + _internalFlow.setTransform(sensorToWorldScale, worldPosition, worldRotation * Quaternions::Y_180); + _networkFlow.setTransform(sensorToWorldScale, worldPosition, worldRotation * Quaternions::Y_180); { glm::vec3 localVel = glm::inverse(worldRotation) * workingVelocity; @@ -1209,10 +1209,21 @@ void Rig::updateAnimations(float deltaTime, const glm::mat4& rootTransform, cons } applyOverridePoses(); - buildAbsoluteRigPoses(_internalPoseSet._relativePoses, _internalPoseSet._absolutePoses); - buildAbsoluteRigPoses(_networkPoseSet._relativePoses, _networkPoseSet._absolutePoses); + + buildAbsoluteRigPoses(_internalPoseSet._relativePoses, _internalPoseSet._absolutePoses); + _internalFlow.update(deltaTime, _internalPoseSet._relativePoses, _internalPoseSet._absolutePoses, _internalPoseSet._overrideFlags); + + if (_sendNetworkNode) { + if (_internalFlow.getActive() && !_networkFlow.getActive()) { + _networkFlow = _internalFlow; + } + buildAbsoluteRigPoses(_networkPoseSet._relativePoses, _networkPoseSet._absolutePoses); + _networkFlow.update(deltaTime, _networkPoseSet._relativePoses, _networkPoseSet._absolutePoses, _internalPoseSet._overrideFlags); + } else if (_networkFlow.getActive()) { + _networkFlow.setActive(false); + } + // copy internal poses to external poses - _flow.update(deltaTime); { QWriteLocker writeLock(&_externalPoseSetLock); @@ -1899,11 +1910,15 @@ void Rig::initAnimGraph(const QUrl& url) { connect(_networkLoader.get(), &AnimNodeLoader::error, [networkUrl](int error, QString str) { qCritical(animation) << "Error loading: code = " << error << "str =" << str; }); + + /* connect(this, &Rig::onLoadComplete, [&]() { - if (_flow.isActive()) { - _flow.calculateConstraints(); + if (_internalFlow.getActive()) { + _internalFlow.calculateConstraints(_animSkeleton, _internalPoseSet._relativePoses, _internalPoseSet._absolutePoses); + _networkFlow.calculateConstraints(_animSkeleton, _internalPoseSet._relativePoses, _internalPoseSet._absolutePoses); } }); + */ } } @@ -2111,3 +2126,15 @@ void Rig::computeAvatarBoundingCapsule( glm::vec3 capsuleCenter = transformPoint(_geometryToRigTransform, (0.5f * (totalExtents.maximum + totalExtents.minimum))); localOffsetOut = capsuleCenter - hipsPosition; } + +void Rig::initFlow(bool isActive) { + _internalFlow.setActive(isActive); + if (isActive) { + if (!_internalFlow.isInitialized()) { + _internalFlow.calculateConstraints(_animSkeleton, _internalPoseSet._relativePoses, _internalPoseSet._absolutePoses); + _networkFlow.calculateConstraints(_animSkeleton, _internalPoseSet._relativePoses, _internalPoseSet._absolutePoses); + } + } else { + _internalFlow.cleanUp(); + } +} \ No newline at end of file diff --git a/libraries/animation/src/Rig.h b/libraries/animation/src/Rig.h index 47c9697dac..2f0e2ad65b 100644 --- a/libraries/animation/src/Rig.h +++ b/libraries/animation/src/Rig.h @@ -234,8 +234,9 @@ public: const AnimContext::DebugAlphaMap& getDebugAlphaMap() const { return _lastContext.getDebugAlphaMap(); } const AnimVariantMap& getAnimVars() const { return _lastAnimVars; } const AnimContext::DebugStateMachineMap& getStateMachineMap() const { return _lastContext.getStateMachineMap(); } - void computeFlowSkeleton() { _flow.calculateConstraints(); } - Flow& getFlow() { return _flow; } + void initFlow(bool isActive); + Flow& getFlow() { return _internalFlow; } + signals: void onLoadComplete(); @@ -427,7 +428,8 @@ protected: SnapshotBlendPoseHelper _hipsBlendHelper; ControllerParameters _previousControllerParameters; - Flow _flow; + Flow _internalFlow; + Flow _networkFlow; }; #endif /* defined(__hifi__Rig__) */ diff --git a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp index 3b1065a3ca..be5eea5161 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp +++ b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp @@ -729,18 +729,15 @@ void Avatar::postUpdate(float deltaTime, const render::ScenePointer& scene) { } const bool DEBUG_FLOW = true; if (_skeletonModel->isLoaded() && DEBUG_FLOW) { - auto flow = _skeletonModel->getRig().getFlow(); - auto joints = flow.getJoints(); - auto threads = flow.getThreads(); + Flow* flow = _skeletonModel->getRig().getFlow(); + auto joints = flow->getJoints(); + auto threads = flow->getThreads(); for (auto &thread : threads) { auto& jointIndexes = thread._joints; for (size_t i = 1; i < jointIndexes.size(); i++) { auto index1 = jointIndexes[i - 1]; auto index2 = jointIndexes[i]; - // glm::vec3 pos1 = joint.second._node._currentPosition; - // glm::vec3 pos2 = joints.find(joint.second._parentIndex) != joints.end() ? joints[joint.second._parentIndex]._node._currentPosition : getJointPosition(joint.second._parentIndex); - // DebugDraw::getInstance().drawRay(pos1, pos2, glm::vec4(1.0f, 1.0f, 1.0f, 1.0f)); - DebugDraw::getInstance().drawRay(joints[index1]._node._currentPosition, joints[index2]._node._currentPosition, glm::vec4(1.0f, 1.0f, 1.0f, 1.0f)); + DebugDraw::getInstance().drawRay(joints[index1].getCurrentPosition(), joints[index2].getCurrentPosition(), glm::vec4(1.0f, 1.0f, 1.0f, 1.0f)); } } } From 951380db15f8f36d3dc21a206a0cecbc51b6046e Mon Sep 17 00:00:00 2001 From: amantley Date: Tue, 19 Feb 2019 17:53:59 -0800 Subject: [PATCH 090/112] tweaked the constraints, to do: start conditions and possibly using base rotation on shoulder to determine hand offset --- .../src/AnimPoleVectorConstraint.cpp | 2 +- libraries/animation/src/Rig.cpp | 300 ++++++++++-------- 2 files changed, 172 insertions(+), 130 deletions(-) diff --git a/libraries/animation/src/AnimPoleVectorConstraint.cpp b/libraries/animation/src/AnimPoleVectorConstraint.cpp index afcf9b29ee..36c58ecb4e 100644 --- a/libraries/animation/src/AnimPoleVectorConstraint.cpp +++ b/libraries/animation/src/AnimPoleVectorConstraint.cpp @@ -124,7 +124,7 @@ const AnimPoseVec& AnimPoleVectorConstraint::evaluate(const AnimVariantMap& anim glm::quat deltaRot = glm::angleAxis(theta, unitAxis); if (_tipJointName == "RightHand") { - qCDebug(animation) << "anim ik theta " << (theta / PI)*180.0f; + //qCDebug(animation) << "anim ik theta " << (theta / PI)*180.0f; } // transform result back into parent relative frame. diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index 48ffdb4970..02d9f66cf5 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -1691,22 +1691,8 @@ void Rig::updateEyeJoint(int index, const glm::vec3& modelTranslation, const glm } } -bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int shoulderIndex, bool left, glm::vec3& poleVector) { - // get the default poses for the upper and lower arm - // then use this length to judge how far the hand is away from the shoulder. - // then create weights that make the elbow angle less when the x value is large in either direction. - // make the angle less when z is small. - // lower y with x center lower angle - // lower y with x out higher angle - - AnimPose handPose = _externalPoseSet._absolutePoses[handIndex]; - AnimPose shoulderPose = _externalPoseSet._absolutePoses[shoulderIndex]; - AnimPose elbowPose = _externalPoseSet._absolutePoses[elbowIndex]; - - AnimPose absoluteShoulderPose = getAbsoluteDefaultPose(shoulderIndex); - AnimPose absoluteHandPose = getAbsoluteDefaultPose(handIndex); - float defaultArmLength = glm::length(absoluteHandPose.trans() - absoluteShoulderPose.trans()); - +static float getHandPositionTheta(glm::vec3 armToHand, float defaultArmLength) { + float handPositionTheta = 0.0f; //calculate the hand position influence on theta const float zStart = 0.6f; const float xStart = 0.1f; @@ -1715,14 +1701,7 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s // weights const float zWeightBottom = -100.0f; const glm::vec3 weights(-50.0f, 60.0f, 90.0f); - glm::vec3 armToHand = handPose.trans() - shoulderPose.trans(); - glm::vec3 unitAxis; - float axisLength = glm::length(armToHand); - if (axisLength > 0.0f) { - unitAxis = armToHand / axisLength; - } else { - unitAxis = Vectors::UNIT_Y; - } + float yFactor = (fabsf(armToHand[1] / defaultArmLength) * weights[1]) + biases[1]; @@ -1742,19 +1721,157 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s } float theta = xFactor + yFactor + zFactor; - //float theta = yFactor; - if (theta < 13.0f) { - theta = 13.0f; + if (handPositionTheta < 13.0f) { + handPositionTheta = 13.0f; } - if (theta > 175.0f) { - theta = 175.0f; + if (handPositionTheta > 175.0f) { + handPositionTheta = 175.0f; } if (left) { - theta *= -1.0f; + handPositionTheta *= -1.0f; } + + return handPositionTheta; +} + +static float computeUlnarRadialCompensation(float ulnarRadialTheta, float twistTheta, bool left) { + const float ULNAR_BOUNDARY_MINUS = PI / 6.0f; + const float ULNAR_BOUNDARY_PLUS = -PI / 4.0f; + float ulnarDiff = 0.0f; + float ulnarCorrection = 0.0f; + float currentWristCoefficient = 0.0f; + if (left) { + if (ulnarRadialTheta > ULNAR_BOUNDARY_MINUS) { + ulnarDiff = ulnarRadialTheta - ULNAR_BOUNDARY_MINUS; + } else if (ulnarRadialTheta < ULNAR_BOUNDARY_PLUS) { + ulnarDiff = ulnarRadialTheta - ULNAR_BOUNDARY_PLUS; + } + if (fabsf(ulnarDiff) > 0.0f) { + float twistCoefficient = (fabsf(twistTheta) / (PI / 20.0f)); + if (twistCoefficient > 1.0f) { + twistCoefficient = 1.0f; + } + if (twistTheta < 0.0f) { + ulnarCorrection -= glm::sign(ulnarDiff) * (fabsf(ulnarDiff) / PI) * 90.0f * twistCoefficient; + } else { + ulnarCorrection += glm::sign(ulnarDiff) * (fabsf(ulnarDiff) / PI) * 90.0f * twistCoefficient; + } + if (fabsf(ulnarCorrection) > 20.0f) { + ulnarCorrection = glm::sign(ulnarCorrection) * 20.0f; + } + // return this --V + currentWristCoefficient += ulnarCorrection; + } + } else { + if (ulnarRadialTheta > ULNAR_BOUNDARY_MINUS) { + ulnarDiff = ulnarRadialTheta - ULNAR_BOUNDARY_MINUS; + } else if (ulnarRadialTheta < ULNAR_BOUNDARY_PLUS) { + ulnarDiff = ulnarRadialTheta - ULNAR_BOUNDARY_PLUS; + } + if (fabsf(ulnarDiff) > 0.0f) { + float twistCoefficient = (fabsf(twistTheta) / (PI / 20.0f)); + if (twistCoefficient > 1.0f) { + twistCoefficient = 1.0f; + } + if (twistTheta < 0.0f) { + ulnarCorrection += glm::sign(ulnarDiff) * (fabsf(ulnarDiff) / PI) * 90.0f * twistCoefficient; + } else { + ulnarCorrection -= glm::sign(ulnarDiff) * (fabsf(ulnarDiff) / PI) * 90.0f * twistCoefficient; + } + if (fabsf(ulnarCorrection) > 20.0f) { + ulnarCorrection = glm::sign(ulnarCorrection) * 20.0f; + } + currentWristCoefficient += ulnarCorrection; + } + } + + return currentWristCoefficient; + + +} + +static float computeTwistCompensation(float twistTheta, bool left) { + + const float TWIST_DEADZONE = (4 * PI) / 9.0f; + float twistCorrection = 0.0f; + if (left) { + if (fabsf(twistTheta) > TWIST_DEADZONE) { + twistCorrection = glm::sign(twistTheta) * ((fabsf(twistTheta) - TWIST_DEADZONE) / PI) * 100.0f; + } + } else { + if (fabsf(twistTheta) > TWIST_DEADZONE) { + twistCorrection = glm::sign(twistTheta) * ((fabsf(twistTheta) - TWIST_DEADZONE) / PI) * 100.0f; + } + } + // limit the twist correction + if (fabsf(twistCorrection) > 30.0f) { + twistCorrection = glm::sign(twistCorrection) * 30.0f; + } + + return twistCorrection; +} + +static float computeFlexCompensation(float flexTheta, bool left) { + + const float FLEX_BOUNDARY = PI / 6.0f; + const float EXTEND_BOUNDARY = -PI / 4.0f; + float flexCorrection = 0.0f; + float currentWristCoefficient = 0.0f; + if (left) { + if (flexTheta > FLEX_BOUNDARY) { + flexCorrection = ((flexTheta - FLEX_BOUNDARY) / PI) * 180.0f; + } else if (flexTheta < EXTEND_BOUNDARY) { + flexCorrection = ((flexTheta - EXTEND_BOUNDARY) / PI) * 180.0f; + } + if (fabsf(flexCorrection) > 175.0f) { + flexCorrection = glm::sign(flexCorrection) * 175.0f; + } + currentWristCoefficient += flexCorrection; + } else { + if (flexTheta > FLEX_BOUNDARY) { + flexCorrection = ((flexTheta - FLEX_BOUNDARY) / PI) * 180.0f; + } else if (flexTheta < EXTEND_BOUNDARY) { + flexCorrection = ((flexTheta - EXTEND_BOUNDARY) / PI) * 180.0f; + } + if (fabsf(flexCorrection) > 175.0f) { + flexCorrection = glm::sign(flexCorrection) * 175.0f; + } + currentWristCoefficient -= flexCorrection; + } + + return currentWristCoefficient; + +} + +bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int shoulderIndex, bool left, glm::vec3& poleVector) { + // get the default poses for the upper and lower arm + // then use this length to judge how far the hand is away from the shoulder. + // then create weights that make the elbow angle less when the x value is large in either direction. + // make the angle less when z is small. + // lower y with x center lower angle + // lower y with x out higher angle + + AnimPose handPose = _externalPoseSet._absolutePoses[handIndex]; + AnimPose shoulderPose = _externalPoseSet._absolutePoses[shoulderIndex]; + AnimPose elbowPose = _externalPoseSet._absolutePoses[elbowIndex]; + + AnimPose absoluteShoulderPose = getAbsoluteDefaultPose(shoulderIndex); + AnimPose absoluteHandPose = getAbsoluteDefaultPose(handIndex); + float defaultArmLength = glm::length(absoluteHandPose.trans() - absoluteShoulderPose.trans()); + glm::vec3 armToHand = handPose.trans() - shoulderPose.trans(); + glm::vec3 unitAxis; + float axisLength = glm::length(armToHand); + if (axisLength > 0.0f) { + unitAxis = armToHand / axisLength; + } else { + unitAxis = Vectors::UNIT_Y; + } + + float theta = 175.0f;// getHandPositionTheta(armToHand, defaultArmLength); + float deltaTheta = 0.0f; if (left) { deltaTheta = theta - _lastThetaLeft; @@ -1767,6 +1884,10 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s AnimPose updatedBase = shoulderPose * deltaRot; AnimPose newAbsMid = updatedBase * relMid; + glm::quat axisRotation; + glm::quat nonAxisRotation; + swingTwistDecomposition(updatedBase.rot(), unitAxis, nonAxisRotation, axisRotation); + qCDebug(animation) << "the rotation about the axis of the arm " << (glm::sign(glm::axis(axisRotation)[2]) * glm::angle(axisRotation) / PI)*180.0f << " delta Rot theta " << deltaTheta; // now we calculate the contribution of the hand rotation relative to the arm // we are adding in the delta rotation so that we have the hand correction relative to the @@ -1791,14 +1912,14 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s ulnarDeviationTheta = -1.0f * ulnarDeviationTheta; } // put some smoothing on the theta - _ulnarRadialThetaRunningAverageLeft = 0.5f * _ulnarRadialThetaRunningAverageLeft + 0.5f * ulnarDeviationTheta; + _ulnarRadialThetaRunningAverageLeft = ulnarDeviationTheta; } else { if (glm::sign(ulnarDeviationTheta) != glm::sign(_ulnarRadialThetaRunningAverageRight) && fabsf(ulnarDeviationTheta) > (PI / 2.0f)) { // don't allow the theta to cross the 180 degree limit. ulnarDeviationTheta = -1.0f * ulnarDeviationTheta; } // put some smoothing on the theta - _ulnarRadialThetaRunningAverageRight = 0.75f * _ulnarRadialThetaRunningAverageRight + 0.25f * ulnarDeviationTheta; + _ulnarRadialThetaRunningAverageRight = ulnarDeviationTheta; } //get the flex/extension of the wrist rotation @@ -1851,115 +1972,36 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s _twistThetaRunningAverageRight = 0.5f * _twistThetaRunningAverageRight + 0.5f * trueTwistTheta; } - float currentWristCoefficient = 0.0f; - const float FLEX_BOUNDARY = 0.0f; // PI / 6.0f; - const float EXTEND_BOUNDARY = 0.0f; //-PI / 4.0f; - float flexCorrection = 0.0f; + if (left) { - if (_flexThetaRunningAverageLeft > FLEX_BOUNDARY) { - flexCorrection = ((_flexThetaRunningAverageLeft - FLEX_BOUNDARY) / PI) * 180.0f; - } else if (_flexThetaRunningAverageLeft < EXTEND_BOUNDARY) { - flexCorrection = ((_flexThetaRunningAverageLeft - EXTEND_BOUNDARY) / PI) * 180.0f; - } - if (fabsf(flexCorrection) > 175.0f) { - flexCorrection = glm::sign(flexCorrection) * 175.0f; - } - currentWristCoefficient += flexCorrection; + currentWristCoefficient += computeUlnarRadialCompensation(_ulnarRadialThetaRunningAverageLeft, _twistThetaRunningAverageLeft, left); + currentWristCoefficient += computeTwistCompensation(_twistThetaRunningAverageLeft, left); + currentWristCoefficient += computeFlexCompensation(_flexThetaRunningAverageLeft, left); } else { - if (_flexThetaRunningAverageRight > FLEX_BOUNDARY) { - flexCorrection = ((_flexThetaRunningAverageRight - FLEX_BOUNDARY) / PI) * 180.0f; - } else if (_flexThetaRunningAverageRight < EXTEND_BOUNDARY) { - flexCorrection = ((_flexThetaRunningAverageRight - EXTEND_BOUNDARY) / PI) * 180.0f; - } - if (fabsf(flexCorrection) > 175.0f) { - flexCorrection = glm::sign(flexCorrection) * 175.0f; - } - currentWristCoefficient -= flexCorrection; + currentWristCoefficient += computeUlnarRadialCompensation(_ulnarRadialThetaRunningAverageRight, _twistThetaRunningAverageRight, left); + currentWristCoefficient += computeTwistCompensation(_twistThetaRunningAverageRight, left); + currentWristCoefficient += computeFlexCompensation(_flexThetaRunningAverageRight, left); } - - const float ULNAR_BOUNDARY_MINUS = -PI / 6.0f; - const float ULNAR_BOUNDARY_PLUS = PI / 4.0f; - float ulnarDiff = 0.0f; - float ulnarCorrection = 0.0f; - if (left) { - if (_ulnarRadialThetaRunningAverageLeft > -ULNAR_BOUNDARY_MINUS) { - ulnarDiff = _ulnarRadialThetaRunningAverageLeft + ULNAR_BOUNDARY_MINUS; - } else if (_ulnarRadialThetaRunningAverageLeft < -ULNAR_BOUNDARY_PLUS) { - ulnarDiff = _ulnarRadialThetaRunningAverageLeft + ULNAR_BOUNDARY_PLUS; - } - if (fabsf(ulnarDiff) > 0.0f) { - float twistCoefficient = (fabsf(_twistThetaRunningAverageLeft) / (PI / 20.0f)); - if (twistCoefficient > 1.0f) { - twistCoefficient = 1.0f; - } - if (left) { - if (_twistThetaRunningAverageLeft < 0.0f) { - ulnarCorrection -= glm::sign(ulnarDiff) * (fabsf(ulnarDiff) / PI) * 80.0f * twistCoefficient; - } else { - ulnarCorrection += glm::sign(ulnarDiff) * (fabsf(ulnarDiff) / PI) * 80.0f * twistCoefficient; - } - } - if (fabsf(ulnarCorrection) > 20.0f) { - ulnarCorrection = glm::sign(ulnarCorrection) * 20.0f; - } - currentWristCoefficient += ulnarCorrection; - } - } else { - if (_ulnarRadialThetaRunningAverageRight > ULNAR_BOUNDARY_PLUS) { - ulnarDiff = _ulnarRadialThetaRunningAverageRight - ULNAR_BOUNDARY_PLUS; - } else if (_ulnarRadialThetaRunningAverageRight < ULNAR_BOUNDARY_MINUS) { - ulnarDiff = _ulnarRadialThetaRunningAverageRight - ULNAR_BOUNDARY_MINUS; - } - if (fabsf(ulnarDiff) > 0.0f) { - float twistCoefficient = (fabsf(_twistThetaRunningAverageRight) / (PI / 20.0f)); - if (twistCoefficient > 1.0f) { - twistCoefficient = 1.0f; - } - if (left) { - if (_twistThetaRunningAverageRight < 0.0f) { - ulnarCorrection -= glm::sign(ulnarDiff) * (fabsf(ulnarDiff) / PI) * 80.0f * twistCoefficient; - } else { - ulnarCorrection += glm::sign(ulnarDiff) * (fabsf(ulnarDiff) / PI) * 80.0f * twistCoefficient; - } - } - if (fabsf(ulnarCorrection) > 20.0f) { - ulnarCorrection = glm::sign(ulnarCorrection) * 20.0f; - } - currentWristCoefficient += ulnarCorrection; - } - } - - const float TWIST_DEADZONE = (4 * PI) / 9.0f; - float twistCorrection = 0.0f; - if (left) { - if (fabsf(_twistThetaRunningAverageLeft) > TWIST_DEADZONE) { - twistCorrection = glm::sign(_twistThetaRunningAverageLeft) * ((fabsf(_twistThetaRunningAverageLeft) - TWIST_DEADZONE) / PI) * 80.0f; - } - } else { - if (fabsf(_twistThetaRunningAverageRight) > TWIST_DEADZONE) { - twistCorrection = glm::sign(_twistThetaRunningAverageRight) * ((fabsf(_twistThetaRunningAverageRight) - TWIST_DEADZONE) / PI) * 80.0f; - } - } - // limit the twist correction - if (fabsf(twistCorrection) > 30.0f) { - currentWristCoefficient += glm::sign(twistCorrection) * 30.0f; - } else { - currentWristCoefficient += twistCorrection; - } - + if (left) { _lastWristCoefficientLeft = _lastThetaLeft - theta; _lastWristCoefficientLeft += currentWristCoefficient; theta += _lastWristCoefficientLeft; + if (theta > 0.0f) { + theta = 0.0f; + } } else { _lastWristCoefficientRight = _lastThetaRight - theta; _lastWristCoefficientRight += currentWristCoefficient; theta += _lastWristCoefficientRight; + if (theta < 0.0f) { + theta = 0.0f; + } } - - if (left) { - qCDebug(animation) << "theta " << theta << "Last wrist" << _lastWristCoefficientLeft << " flex ave: " << (_flexThetaRunningAverageLeft / PI) * 180.0f << " twist ave: " << (_twistThetaRunningAverageLeft / PI) * 180.0f << " ulnar deviation ave: " << (_ulnarRadialThetaRunningAverageLeft / PI) * 180.0f; + + if (!left) { + // qCDebug(animation) << "theta " << theta << "Last wrist" << _lastWristCoefficientRight << " flex ave: " << (_flexThetaRunningAverageRight / PI) * 180.0f << " twist ave: " << (_twistThetaRunningAverageRight/ PI) * 180.0f << " ulnar deviation ave: " << (_ulnarRadialThetaRunningAverageRight / PI) * 180.0f; } // global limiting @@ -1982,7 +2024,7 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s if (fabsf(_lastThetaRight) < 10.0f) { - _lastThetaRight = glm::sign(_lastThetaRight) * 10.0f; + _lastThetaRight = glm::sign(_lastThetaRight) * 50.0f; } if (fabsf(_lastThetaRight) > 175.0f) { _lastThetaRight = glm::sign(_lastThetaRight) * 175.0f; From 1e73422b80e495de672e0d80942e58f4702c2dfe Mon Sep 17 00:00:00 2001 From: Angus Antley Date: Wed, 20 Feb 2019 06:25:44 -0800 Subject: [PATCH 091/112] added the wrist and position coeffs back in, 1.0 works --- libraries/animation/src/Rig.cpp | 66 +++++++++++++++++++-------------- libraries/animation/src/Rig.h | 2 + 2 files changed, 41 insertions(+), 27 deletions(-) diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index 02d9f66cf5..2ef3617118 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -1691,7 +1691,7 @@ void Rig::updateEyeJoint(int index, const glm::vec3& modelTranslation, const glm } } -static float getHandPositionTheta(glm::vec3 armToHand, float defaultArmLength) { +static float getHandPositionTheta(glm::vec3 armToHand, float defaultArmLength, bool left) { float handPositionTheta = 0.0f; //calculate the hand position influence on theta const float zStart = 0.6f; @@ -1720,10 +1720,10 @@ static float getHandPositionTheta(glm::vec3 armToHand, float defaultArmLength) { xFactor = weights[0] * (((armToHand[0] / defaultArmLength) + xStart) - (0.2f) * ((1.0f + (armToHand[1] / defaultArmLength)) / 2.0f)); } - float theta = xFactor + yFactor + zFactor; + handPositionTheta = xFactor + yFactor + zFactor; - if (handPositionTheta < 13.0f) { - handPositionTheta = 13.0f; + if (handPositionTheta < 50.0f) { + handPositionTheta = 50.0f; } if (handPositionTheta > 175.0f) { handPositionTheta = 175.0f; @@ -1755,9 +1755,9 @@ static float computeUlnarRadialCompensation(float ulnarRadialTheta, float twistT twistCoefficient = 1.0f; } if (twistTheta < 0.0f) { - ulnarCorrection -= glm::sign(ulnarDiff) * (fabsf(ulnarDiff) / PI) * 90.0f * twistCoefficient; + ulnarCorrection -= glm::sign(ulnarDiff) * (fabsf(ulnarDiff) / PI) * 45.0f * twistCoefficient; } else { - ulnarCorrection += glm::sign(ulnarDiff) * (fabsf(ulnarDiff) / PI) * 90.0f * twistCoefficient; + ulnarCorrection += glm::sign(ulnarDiff) * (fabsf(ulnarDiff) / PI) * 45.0f * twistCoefficient; } if (fabsf(ulnarCorrection) > 20.0f) { ulnarCorrection = glm::sign(ulnarCorrection) * 20.0f; @@ -1777,9 +1777,9 @@ static float computeUlnarRadialCompensation(float ulnarRadialTheta, float twistT twistCoefficient = 1.0f; } if (twistTheta < 0.0f) { - ulnarCorrection += glm::sign(ulnarDiff) * (fabsf(ulnarDiff) / PI) * 90.0f * twistCoefficient; + ulnarCorrection += glm::sign(ulnarDiff) * (fabsf(ulnarDiff) / PI) * 45.0f * twistCoefficient; } else { - ulnarCorrection -= glm::sign(ulnarDiff) * (fabsf(ulnarDiff) / PI) * 90.0f * twistCoefficient; + ulnarCorrection -= glm::sign(ulnarDiff) * (fabsf(ulnarDiff) / PI) * 45.0f * twistCoefficient; } if (fabsf(ulnarCorrection) > 20.0f) { ulnarCorrection = glm::sign(ulnarCorrection) * 20.0f; @@ -1795,7 +1795,7 @@ static float computeUlnarRadialCompensation(float ulnarRadialTheta, float twistT static float computeTwistCompensation(float twistTheta, bool left) { - const float TWIST_DEADZONE = (4 * PI) / 9.0f; + const float TWIST_DEADZONE = PI / 2.0f; float twistCorrection = 0.0f; if (left) { if (fabsf(twistTheta) > TWIST_DEADZONE) { @@ -1822,9 +1822,9 @@ static float computeFlexCompensation(float flexTheta, bool left) { float currentWristCoefficient = 0.0f; if (left) { if (flexTheta > FLEX_BOUNDARY) { - flexCorrection = ((flexTheta - FLEX_BOUNDARY) / PI) * 180.0f; + flexCorrection = ((flexTheta - FLEX_BOUNDARY) / PI) * 60.0f; } else if (flexTheta < EXTEND_BOUNDARY) { - flexCorrection = ((flexTheta - EXTEND_BOUNDARY) / PI) * 180.0f; + flexCorrection = ((flexTheta - EXTEND_BOUNDARY) / PI) * 60.0f; } if (fabsf(flexCorrection) > 175.0f) { flexCorrection = glm::sign(flexCorrection) * 175.0f; @@ -1832,9 +1832,9 @@ static float computeFlexCompensation(float flexTheta, bool left) { currentWristCoefficient += flexCorrection; } else { if (flexTheta > FLEX_BOUNDARY) { - flexCorrection = ((flexTheta - FLEX_BOUNDARY) / PI) * 180.0f; + flexCorrection = ((flexTheta - FLEX_BOUNDARY) / PI) * 60.0f; } else if (flexTheta < EXTEND_BOUNDARY) { - flexCorrection = ((flexTheta - EXTEND_BOUNDARY) / PI) * 180.0f; + flexCorrection = ((flexTheta - EXTEND_BOUNDARY) / PI) * 60.0f; } if (fabsf(flexCorrection) > 175.0f) { flexCorrection = glm::sign(flexCorrection) * 175.0f; @@ -1870,7 +1870,8 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s unitAxis = Vectors::UNIT_Y; } - float theta = 175.0f;// getHandPositionTheta(armToHand, defaultArmLength); + float theta = getHandPositionTheta(armToHand, defaultArmLength, left); + qCDebug(animation) << "hand position theta " << left << " " << theta; float deltaTheta = 0.0f; if (left) { @@ -1887,7 +1888,7 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s glm::quat axisRotation; glm::quat nonAxisRotation; swingTwistDecomposition(updatedBase.rot(), unitAxis, nonAxisRotation, axisRotation); - qCDebug(animation) << "the rotation about the axis of the arm " << (glm::sign(glm::axis(axisRotation)[2]) * glm::angle(axisRotation) / PI)*180.0f << " delta Rot theta " << deltaTheta; + //qCDebug(animation) << "the rotation about the axis of the arm " << (glm::sign(glm::axis(axisRotation)[2]) * glm::angle(axisRotation) / PI)*180.0f << " delta Rot theta " << deltaTheta; // now we calculate the contribution of the hand rotation relative to the arm // we are adding in the delta rotation so that we have the hand correction relative to the @@ -1984,16 +1985,22 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s currentWristCoefficient += computeFlexCompensation(_flexThetaRunningAverageRight, left); } + // i think limit theta here so we don't subtract more than is possible from last theta. + // actually theta is limited. to what though? + if (left) { - _lastWristCoefficientLeft = _lastThetaLeft - theta; + _lastWristCoefficientLeft = _lastThetaLeft - _lastPositionThetaLeft; _lastWristCoefficientLeft += currentWristCoefficient; + _lastPositionThetaLeft = theta; theta += _lastWristCoefficientLeft; if (theta > 0.0f) { theta = 0.0f; } + //qCDebug(animation) << "theta " << theta << " lastThetaLeft " << _lastThetaLeft << "last position theta left"<<_lastPositionThetaLeft << "last wrist coeff " << _lastWristCoefficientLeft; } else { - _lastWristCoefficientRight = _lastThetaRight - theta; + _lastWristCoefficientRight = _lastThetaRight - _lastPositionThetaRight; _lastWristCoefficientRight += currentWristCoefficient; + _lastPositionThetaRight = theta; theta += _lastWristCoefficientRight; if (theta < 0.0f) { theta = 0.0f; @@ -2008,26 +2015,31 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s float thetaRadians = 0.0f; if (left) { // final global smoothing - _lastThetaLeft = 0.5f * _lastThetaLeft + 0.5f * theta; + //_lastThetaLeft = 0.5f * _lastThetaLeft + 0.5f * theta; + _lastThetaLeft = theta; - if (fabsf(_lastThetaLeft) < 50.0f) { - _lastThetaLeft = glm::sign(_lastThetaLeft) * 50.0f; + if (_lastThetaLeft > -50.0f) { + _lastThetaLeft = -50.0f; } - if (fabsf(_lastThetaLeft) > 175.0f) { - _lastThetaLeft = glm::sign(_lastThetaLeft) * 175.0f; + if (_lastThetaLeft < -175.0f) { + _lastThetaLeft = -175.0f; + } + const float MIN_VALUE = 0.0001f; + if (fabsf(_lastPositionThetaLeft - _lastThetaLeft) > MIN_VALUE) { + qCDebug(animation) << "theta " << theta << " lastThetaLeft " << _lastThetaLeft << "last position theta left" << _lastPositionThetaLeft << "last wrist coeff " << _lastWristCoefficientLeft; } // convert to radians and make 180 0 to match pole vector theta thetaRadians = ((180.0f - _lastThetaLeft) / 180.0f)*PI; } else { // final global smoothing - _lastThetaRight = 0.5f * _lastThetaRight + 0.5f * theta; + _lastThetaRight = theta; // 0.5f * _lastThetaRight + 0.5f * theta; - if (fabsf(_lastThetaRight) < 10.0f) { - _lastThetaRight = glm::sign(_lastThetaRight) * 50.0f; + if (_lastThetaRight < 50.0f) { + _lastThetaRight = 50.0f; } - if (fabsf(_lastThetaRight) > 175.0f) { - _lastThetaRight = glm::sign(_lastThetaRight) * 175.0f; + if (_lastThetaRight > 175.0f) { + _lastThetaRight = 175.0f; } // convert to radians and make 180 0 to match pole vector theta thetaRadians = ((180.0f - _lastThetaRight) / 180.0f)*PI; diff --git a/libraries/animation/src/Rig.h b/libraries/animation/src/Rig.h index 7b9c3d238d..6f1a5906bb 100644 --- a/libraries/animation/src/Rig.h +++ b/libraries/animation/src/Rig.h @@ -430,6 +430,8 @@ protected: float _lastThetaRight { 0.0f }; float _lastWristCoefficientRight { 0.0f }; float _lastWristCoefficientLeft { 0.0f }; + float _lastPositionThetaLeft { 0.0f }; + float _lastPositionThetaRight { 0.0f }; AnimContext _lastContext; AnimVariantMap _lastAnimVars; From 7639eac3ad6f2a508ca9c0798d82b705486bd32b Mon Sep 17 00:00:00 2001 From: Angus Antley Date: Wed, 20 Feb 2019 07:18:14 -0800 Subject: [PATCH 092/112] cleaning up theta functions --- libraries/animation/src/Rig.cpp | 84 ++++++++++++++++++++------------- 1 file changed, 51 insertions(+), 33 deletions(-) diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index 2ef3617118..86106e0707 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -1743,6 +1743,7 @@ static float computeUlnarRadialCompensation(float ulnarRadialTheta, float twistT float ulnarDiff = 0.0f; float ulnarCorrection = 0.0f; float currentWristCoefficient = 0.0f; + /* if (left) { if (ulnarRadialTheta > ULNAR_BOUNDARY_MINUS) { ulnarDiff = ulnarRadialTheta - ULNAR_BOUNDARY_MINUS; @@ -1787,6 +1788,35 @@ static float computeUlnarRadialCompensation(float ulnarRadialTheta, float twistT currentWristCoefficient += ulnarCorrection; } } + */ + if (ulnarRadialTheta > ULNAR_BOUNDARY_MINUS) { + ulnarDiff = ulnarRadialTheta - ULNAR_BOUNDARY_MINUS; + } else if (ulnarRadialTheta < ULNAR_BOUNDARY_PLUS) { + ulnarDiff = ulnarRadialTheta - ULNAR_BOUNDARY_PLUS; + } + if (fabsf(ulnarDiff) > 0.0f) { + float twistCoefficient = (fabsf(twistTheta) / (PI / 20.0f)); + if (twistCoefficient > 1.0f) { + twistCoefficient = 1.0f; + } + if (twistTheta < 0.0f) { + if (left) { + ulnarCorrection -= glm::sign(ulnarDiff) * (fabsf(ulnarDiff) / PI) * 45.0f * twistCoefficient; + } else { + ulnarCorrection += glm::sign(ulnarDiff) * (fabsf(ulnarDiff) / PI) * 45.0f * twistCoefficient; + } + } else { + if (left) { + ulnarCorrection += glm::sign(ulnarDiff) * (fabsf(ulnarDiff) / PI) * 45.0f * twistCoefficient; + } else { + ulnarCorrection -= glm::sign(ulnarDiff) * (fabsf(ulnarDiff) / PI) * 45.0f * twistCoefficient; + } + } + if (fabsf(ulnarCorrection) > 20.0f) { + ulnarCorrection = glm::sign(ulnarCorrection) * 20.0f; + } + currentWristCoefficient += ulnarCorrection; + } return currentWristCoefficient; @@ -1797,14 +1827,9 @@ static float computeTwistCompensation(float twistTheta, bool left) { const float TWIST_DEADZONE = PI / 2.0f; float twistCorrection = 0.0f; - if (left) { - if (fabsf(twistTheta) > TWIST_DEADZONE) { - twistCorrection = glm::sign(twistTheta) * ((fabsf(twistTheta) - TWIST_DEADZONE) / PI) * 100.0f; - } - } else { - if (fabsf(twistTheta) > TWIST_DEADZONE) { - twistCorrection = glm::sign(twistTheta) * ((fabsf(twistTheta) - TWIST_DEADZONE) / PI) * 100.0f; - } + + if (fabsf(twistTheta) > TWIST_DEADZONE) { + twistCorrection = glm::sign(twistTheta) * ((fabsf(twistTheta) - TWIST_DEADZONE) / PI) * 100.0f; } // limit the twist correction if (fabsf(twistCorrection) > 30.0f) { @@ -1820,25 +1845,18 @@ static float computeFlexCompensation(float flexTheta, bool left) { const float EXTEND_BOUNDARY = -PI / 4.0f; float flexCorrection = 0.0f; float currentWristCoefficient = 0.0f; + + if (flexTheta > FLEX_BOUNDARY) { + flexCorrection = ((flexTheta - FLEX_BOUNDARY) / PI) * 60.0f; + } else if (flexTheta < EXTEND_BOUNDARY) { + flexCorrection = ((flexTheta - EXTEND_BOUNDARY) / PI) * 60.0f; + } + if (fabsf(flexCorrection) > 175.0f) { + flexCorrection = glm::sign(flexCorrection) * 175.0f; + } if (left) { - if (flexTheta > FLEX_BOUNDARY) { - flexCorrection = ((flexTheta - FLEX_BOUNDARY) / PI) * 60.0f; - } else if (flexTheta < EXTEND_BOUNDARY) { - flexCorrection = ((flexTheta - EXTEND_BOUNDARY) / PI) * 60.0f; - } - if (fabsf(flexCorrection) > 175.0f) { - flexCorrection = glm::sign(flexCorrection) * 175.0f; - } currentWristCoefficient += flexCorrection; } else { - if (flexTheta > FLEX_BOUNDARY) { - flexCorrection = ((flexTheta - FLEX_BOUNDARY) / PI) * 60.0f; - } else if (flexTheta < EXTEND_BOUNDARY) { - flexCorrection = ((flexTheta - EXTEND_BOUNDARY) / PI) * 60.0f; - } - if (fabsf(flexCorrection) > 175.0f) { - flexCorrection = glm::sign(flexCorrection) * 175.0f; - } currentWristCoefficient -= flexCorrection; } @@ -1870,14 +1888,14 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s unitAxis = Vectors::UNIT_Y; } - float theta = getHandPositionTheta(armToHand, defaultArmLength, left); - qCDebug(animation) << "hand position theta " << left << " " << theta; + float positionalTheta = getHandPositionTheta(armToHand, defaultArmLength, left); + qCDebug(animation) << "hand position theta " << left << " " << positionalTheta; float deltaTheta = 0.0f; if (left) { - deltaTheta = theta - _lastThetaLeft; + deltaTheta = positionalTheta - _lastThetaLeft; } else { - deltaTheta = theta - _lastThetaRight; + deltaTheta = positionalTheta - _lastThetaRight; } float deltaThetaRadians = (deltaTheta / 180.0f)*PI; AnimPose deltaRot(glm::angleAxis(deltaThetaRadians, unitAxis), glm::vec3()); @@ -1987,12 +2005,12 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s // i think limit theta here so we don't subtract more than is possible from last theta. // actually theta is limited. to what though? - + float theta = 0.0f; if (left) { _lastWristCoefficientLeft = _lastThetaLeft - _lastPositionThetaLeft; _lastWristCoefficientLeft += currentWristCoefficient; - _lastPositionThetaLeft = theta; - theta += _lastWristCoefficientLeft; + _lastPositionThetaLeft = positionalTheta; + theta = positionalTheta + _lastWristCoefficientLeft; if (theta > 0.0f) { theta = 0.0f; } @@ -2000,8 +2018,8 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s } else { _lastWristCoefficientRight = _lastThetaRight - _lastPositionThetaRight; _lastWristCoefficientRight += currentWristCoefficient; - _lastPositionThetaRight = theta; - theta += _lastWristCoefficientRight; + _lastPositionThetaRight = positionalTheta; + theta += positionalTheta + _lastWristCoefficientRight; if (theta < 0.0f) { theta = 0.0f; } From fa44687de6caad2ee9242f504948174a9758db71 Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Wed, 20 Feb 2019 09:22:39 -0700 Subject: [PATCH 093/112] fix errors and remove debug draw --- libraries/animation/src/Flow.cpp | 4 ++-- .../src/avatars-renderer/Avatar.cpp | 14 -------------- 2 files changed, 2 insertions(+), 16 deletions(-) diff --git a/libraries/animation/src/Flow.cpp b/libraries/animation/src/Flow.cpp index 86252b698d..480ded2002 100644 --- a/libraries/animation/src/Flow.cpp +++ b/libraries/animation/src/Flow.cpp @@ -659,8 +659,8 @@ void Flow::updateAbsolutePoses(const AnimPoseVec& relativePoses, AnimPoseVec& ab for (auto &joint : _flowJointData) { int index = joint.second.getIndex(); int parentIndex = joint.second.getParentIndex(); - if (index >= 0 && index < relativePoses.size() && - parentIndex >= 0 && parentIndex < absolutePoses.size()) { + if (index >= 0 && index < (int)relativePoses.size() && + parentIndex >= 0 && parentIndex < (int)absolutePoses.size()) { absolutePoses[index] = absolutePoses[parentIndex] * relativePoses[index]; } } diff --git a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp index be5eea5161..e6881b0efe 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp +++ b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp @@ -727,20 +727,6 @@ void Avatar::postUpdate(float deltaTime, const render::ScenePointer& scene) { DebugDraw::getInstance().drawRay(rightEyePosition, rightEyePosition + rightEyeRotation * Vectors::UNIT_Z * EYE_RAY_LENGTH, RED); } } - const bool DEBUG_FLOW = true; - if (_skeletonModel->isLoaded() && DEBUG_FLOW) { - Flow* flow = _skeletonModel->getRig().getFlow(); - auto joints = flow->getJoints(); - auto threads = flow->getThreads(); - for (auto &thread : threads) { - auto& jointIndexes = thread._joints; - for (size_t i = 1; i < jointIndexes.size(); i++) { - auto index1 = jointIndexes[i - 1]; - auto index2 = jointIndexes[i]; - DebugDraw::getInstance().drawRay(joints[index1].getCurrentPosition(), joints[index2].getCurrentPosition(), glm::vec4(1.0f, 1.0f, 1.0f, 1.0f)); - } - } - } fixupModelsInScene(scene); updateFitBoundingBox(); From bea7680864f4d7f39621701fce973f925169934c Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Wed, 20 Feb 2019 10:57:11 -0700 Subject: [PATCH 094/112] Fix shared_ptr not part of std error --- libraries/animation/src/Flow.h | 1 + 1 file changed, 1 insertion(+) diff --git a/libraries/animation/src/Flow.h b/libraries/animation/src/Flow.h index e3e20e25f9..5fe7b7acbc 100644 --- a/libraries/animation/src/Flow.h +++ b/libraries/animation/src/Flow.h @@ -11,6 +11,7 @@ #ifndef hifi_Flow_h #define hifi_Flow_h +#include #include #include #include From 95b3fbdc35de9d9569052aa97840965005d9fb52 Mon Sep 17 00:00:00 2001 From: amantley Date: Wed, 20 Feb 2019 15:02:12 -0800 Subject: [PATCH 095/112] removed ulnar coeff, too jumpy --- libraries/animation/src/Rig.cpp | 282 ++++++++++++++------------------ 1 file changed, 119 insertions(+), 163 deletions(-) diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index 86106e0707..7273ccf637 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -1738,33 +1738,16 @@ static float getHandPositionTheta(glm::vec3 armToHand, float defaultArmLength, b } static float computeUlnarRadialCompensation(float ulnarRadialTheta, float twistTheta, bool left) { - const float ULNAR_BOUNDARY_MINUS = PI / 6.0f; + const float ULNAR_BOUNDARY_MINUS = -PI / 4.0f; const float ULNAR_BOUNDARY_PLUS = -PI / 4.0f; float ulnarDiff = 0.0f; float ulnarCorrection = 0.0f; float currentWristCoefficient = 0.0f; - /* if (left) { - if (ulnarRadialTheta > ULNAR_BOUNDARY_MINUS) { - ulnarDiff = ulnarRadialTheta - ULNAR_BOUNDARY_MINUS; - } else if (ulnarRadialTheta < ULNAR_BOUNDARY_PLUS) { - ulnarDiff = ulnarRadialTheta - ULNAR_BOUNDARY_PLUS; - } - if (fabsf(ulnarDiff) > 0.0f) { - float twistCoefficient = (fabsf(twistTheta) / (PI / 20.0f)); - if (twistCoefficient > 1.0f) { - twistCoefficient = 1.0f; - } - if (twistTheta < 0.0f) { - ulnarCorrection -= glm::sign(ulnarDiff) * (fabsf(ulnarDiff) / PI) * 45.0f * twistCoefficient; - } else { - ulnarCorrection += glm::sign(ulnarDiff) * (fabsf(ulnarDiff) / PI) * 45.0f * twistCoefficient; - } - if (fabsf(ulnarCorrection) > 20.0f) { - ulnarCorrection = glm::sign(ulnarCorrection) * 20.0f; - } - // return this --V - currentWristCoefficient += ulnarCorrection; + if (ulnarRadialTheta > -ULNAR_BOUNDARY_MINUS) { + ulnarDiff = ulnarRadialTheta - (-ULNAR_BOUNDARY_MINUS); + } else if (ulnarRadialTheta < -ULNAR_BOUNDARY_PLUS) { + ulnarDiff = ulnarRadialTheta - (-ULNAR_BOUNDARY_PLUS); } } else { if (ulnarRadialTheta > ULNAR_BOUNDARY_MINUS) { @@ -1772,48 +1755,43 @@ static float computeUlnarRadialCompensation(float ulnarRadialTheta, float twistT } else if (ulnarRadialTheta < ULNAR_BOUNDARY_PLUS) { ulnarDiff = ulnarRadialTheta - ULNAR_BOUNDARY_PLUS; } - if (fabsf(ulnarDiff) > 0.0f) { - float twistCoefficient = (fabsf(twistTheta) / (PI / 20.0f)); - if (twistCoefficient > 1.0f) { - twistCoefficient = 1.0f; - } - if (twistTheta < 0.0f) { - ulnarCorrection += glm::sign(ulnarDiff) * (fabsf(ulnarDiff) / PI) * 45.0f * twistCoefficient; - } else { - ulnarCorrection -= glm::sign(ulnarDiff) * (fabsf(ulnarDiff) / PI) * 45.0f * twistCoefficient; - } - if (fabsf(ulnarCorrection) > 20.0f) { - ulnarCorrection = glm::sign(ulnarCorrection) * 20.0f; - } - currentWristCoefficient += ulnarCorrection; - } - } - */ - if (ulnarRadialTheta > ULNAR_BOUNDARY_MINUS) { - ulnarDiff = ulnarRadialTheta - ULNAR_BOUNDARY_MINUS; - } else if (ulnarRadialTheta < ULNAR_BOUNDARY_PLUS) { - ulnarDiff = ulnarRadialTheta - ULNAR_BOUNDARY_PLUS; + } if (fabsf(ulnarDiff) > 0.0f) { - float twistCoefficient = (fabsf(twistTheta) / (PI / 20.0f)); - if (twistCoefficient > 1.0f) { - twistCoefficient = 1.0f; + float twistCoefficient = 0.0f; + + if (left) { + twistCoefficient = twistTheta; + if (twistCoefficient > (PI / 6.0f)) { + twistCoefficient = 1.0f; + } else { + twistCoefficient = 0.0f; + } + } else { + twistCoefficient = twistTheta; + if (twistCoefficient < (-PI / 6.0f)) { + twistCoefficient = 1.0f; + } else { + twistCoefficient = 0.0f; + } + } + if (twistTheta < 0.0f) { if (left) { - ulnarCorrection -= glm::sign(ulnarDiff) * (fabsf(ulnarDiff) / PI) * 45.0f * twistCoefficient; + ulnarCorrection -= glm::sign(ulnarDiff) * (fabsf(ulnarDiff) / PI) * 180.0f * twistCoefficient; } else { - ulnarCorrection += glm::sign(ulnarDiff) * (fabsf(ulnarDiff) / PI) * 45.0f * twistCoefficient; + ulnarCorrection += glm::sign(ulnarDiff) * (fabsf(ulnarDiff) / PI) * 180.0f * twistCoefficient; } } else { if (left) { - ulnarCorrection += glm::sign(ulnarDiff) * (fabsf(ulnarDiff) / PI) * 45.0f * twistCoefficient; + ulnarCorrection += glm::sign(ulnarDiff) * (fabsf(ulnarDiff) / PI) * 180.0f * twistCoefficient; } else { - ulnarCorrection -= glm::sign(ulnarDiff) * (fabsf(ulnarDiff) / PI) * 45.0f * twistCoefficient; + ulnarCorrection -= glm::sign(ulnarDiff) * (fabsf(ulnarDiff) / PI) * 180.0f * twistCoefficient; } } - if (fabsf(ulnarCorrection) > 20.0f) { - ulnarCorrection = glm::sign(ulnarCorrection) * 20.0f; + if (fabsf(ulnarCorrection) > 100.0f) { + ulnarCorrection = glm::sign(ulnarCorrection) * 100.0f; } currentWristCoefficient += ulnarCorrection; } @@ -1829,7 +1807,7 @@ static float computeTwistCompensation(float twistTheta, bool left) { float twistCorrection = 0.0f; if (fabsf(twistTheta) > TWIST_DEADZONE) { - twistCorrection = glm::sign(twistTheta) * ((fabsf(twistTheta) - TWIST_DEADZONE) / PI) * 100.0f; + twistCorrection = glm::sign(twistTheta) * ((fabsf(twistTheta) - TWIST_DEADZONE) / PI) * 90.0f; } // limit the twist correction if (fabsf(twistCorrection) > 30.0f) { @@ -1864,13 +1842,22 @@ static float computeFlexCompensation(float flexTheta, bool left) { } +static float getAxisThetaFromRotation(glm::vec3 axis, glm::quat rotation) { + + //get the flex/extension of the wrist rotation + glm::quat rotationAboutTheAxis; + glm::quat rotationOrthoganalToAxis; + swingTwistDecomposition(rotation, axis, rotationOrthoganalToAxis, rotationAboutTheAxis); + if (rotationAboutTheAxis.w < 0.0f) { + rotationAboutTheAxis *= -1.0f; + } + glm::vec3 rotAxis = glm::axis(rotationAboutTheAxis); + float axisTheta = glm::sign(glm::dot(rotAxis, axis)) * glm::angle(rotationAboutTheAxis); + + return axisTheta; +} + bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int shoulderIndex, bool left, glm::vec3& poleVector) { - // get the default poses for the upper and lower arm - // then use this length to judge how far the hand is away from the shoulder. - // then create weights that make the elbow angle less when the x value is large in either direction. - // make the angle less when z is small. - // lower y with x center lower angle - // lower y with x out higher angle AnimPose handPose = _externalPoseSet._absolutePoses[handIndex]; AnimPose shoulderPose = _externalPoseSet._absolutePoses[shoulderIndex]; @@ -1879,6 +1866,7 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s AnimPose absoluteShoulderPose = getAbsoluteDefaultPose(shoulderIndex); AnimPose absoluteHandPose = getAbsoluteDefaultPose(handIndex); float defaultArmLength = glm::length(absoluteHandPose.trans() - absoluteShoulderPose.trans()); + glm::vec3 armToHand = handPose.trans() - shoulderPose.trans(); glm::vec3 unitAxis; float axisLength = glm::length(armToHand); @@ -1888,9 +1876,11 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s unitAxis = Vectors::UNIT_Y; } + // get the pole vector theta based on the hand position relative to the shoulder. float positionalTheta = getHandPositionTheta(armToHand, defaultArmLength, left); - qCDebug(animation) << "hand position theta " << left << " " << positionalTheta; + //qCDebug(animation) << "hand position theta " << left << " " << positionalTheta; + /* float deltaTheta = 0.0f; if (left) { deltaTheta = positionalTheta - _lastThetaLeft; @@ -1907,166 +1897,132 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s glm::quat nonAxisRotation; swingTwistDecomposition(updatedBase.rot(), unitAxis, nonAxisRotation, axisRotation); //qCDebug(animation) << "the rotation about the axis of the arm " << (glm::sign(glm::axis(axisRotation)[2]) * glm::angle(axisRotation) / PI)*180.0f << " delta Rot theta " << deltaTheta; + + //glm::quat relativeHandRotation = (newAbsMid.inverse() * handPose).rot(); + */ // now we calculate the contribution of the hand rotation relative to the arm - // we are adding in the delta rotation so that we have the hand correction relative to the - // latest theta for hand position - //glm::quat relativeHandRotation = (newAbsMid.inverse() * handPose).rot(); glm::quat relativeHandRotation = (elbowPose.inverse() * handPose).rot(); if (relativeHandRotation.w < 0.0f) { relativeHandRotation *= -1.0f; } - glm::quat ulnarDeviation; - glm::quat nonUlnarDeviation; - swingTwistDecomposition(relativeHandRotation, Vectors::UNIT_Z, nonUlnarDeviation, ulnarDeviation); - if (ulnarDeviation.w < 0.0f) { - ulnarDeviation *= 1.0f; - } - glm::vec3 ulnarAxis = glm::axis(ulnarDeviation); - float ulnarDeviationTheta = glm::sign(ulnarAxis[2]) * glm::angle(ulnarDeviation); + // find the thetas, hand relative to avatar arm + const glm::vec3 ULNAR_ROTATION_AXIS = Vectors::UNIT_Z; + const glm::vec3 TWIST_ROTATION_AXIS = Vectors::UNIT_Y; + const glm::vec3 FLEX__ROTATION_AXIS = Vectors::UNIT_X; + + float ulnarDeviationTheta = getAxisThetaFromRotation(ULNAR_ROTATION_AXIS, relativeHandRotation); + float flexTheta = getAxisThetaFromRotation(FLEX__ROTATION_AXIS, relativeHandRotation); + float trueTwistTheta = getAxisThetaFromRotation(TWIST_ROTATION_AXIS, relativeHandRotation); + + const float HALFWAY_ANGLE = PI / 2.0f; + const float SMOOTHING_COEFFICIENT = 0.5f; if (left) { - if (glm::sign(ulnarDeviationTheta) != glm::sign(_ulnarRadialThetaRunningAverageLeft) && fabsf(ulnarDeviationTheta) > (PI / 2.0f)) { - // don't allow the theta to cross the 180 degree limit. + + if (glm::sign(ulnarDeviationTheta) != glm::sign(_ulnarRadialThetaRunningAverageLeft) && fabsf(ulnarDeviationTheta) > HALFWAY_ANGLE) { + // don't allow the theta to cross the 180 degree limit. ie don't go from 179 to -179 degrees ulnarDeviationTheta = -1.0f * ulnarDeviationTheta; } - // put some smoothing on the theta + if (glm::sign(flexTheta) != glm::sign(_flexThetaRunningAverageLeft) && fabsf(flexTheta) > HALFWAY_ANGLE) { + // don't allow the theta to cross the 180 degree limit. + flexTheta = -1.0f * flexTheta; + } + if (glm::sign(trueTwistTheta) != glm::sign(_twistThetaRunningAverageLeft) && fabsf(trueTwistTheta) > HALFWAY_ANGLE) { + // don't allow the theta to cross the 180 degree limit. + trueTwistTheta = -1.0f * trueTwistTheta; + } + + // put some smoothing on the thetas _ulnarRadialThetaRunningAverageLeft = ulnarDeviationTheta; + _flexThetaRunningAverageLeft = SMOOTHING_COEFFICIENT * _flexThetaRunningAverageLeft + (1.0f - SMOOTHING_COEFFICIENT) * flexTheta; + _twistThetaRunningAverageLeft = SMOOTHING_COEFFICIENT * _twistThetaRunningAverageLeft + (1.0f - SMOOTHING_COEFFICIENT) * trueTwistTheta; + } else { - if (glm::sign(ulnarDeviationTheta) != glm::sign(_ulnarRadialThetaRunningAverageRight) && fabsf(ulnarDeviationTheta) > (PI / 2.0f)) { - // don't allow the theta to cross the 180 degree limit. + + if (glm::sign(ulnarDeviationTheta) != glm::sign(_ulnarRadialThetaRunningAverageRight) && fabsf(ulnarDeviationTheta) > HALFWAY_ANGLE) { + // don't allow the theta to cross the 180 degree limit. ie don't go from 179 to -179 degrees ulnarDeviationTheta = -1.0f * ulnarDeviationTheta; } - // put some smoothing on the theta + if (glm::sign(flexTheta) != glm::sign(_flexThetaRunningAverageRight) && fabsf(flexTheta) > HALFWAY_ANGLE) { + // don't allow the theta to cross the 180 degree limit. + flexTheta = -1.0f * flexTheta; + } + if (glm::sign(trueTwistTheta) != glm::sign(_twistThetaRunningAverageRight) && fabsf(trueTwistTheta) > HALFWAY_ANGLE) { + // don't allow the theta to cross the 180 degree limit. + trueTwistTheta = -1.0f * trueTwistTheta; + } + + // put some smoothing on the thetas + _twistThetaRunningAverageRight = SMOOTHING_COEFFICIENT * _twistThetaRunningAverageRight + (1.0f - SMOOTHING_COEFFICIENT) * trueTwistTheta; + _flexThetaRunningAverageRight = SMOOTHING_COEFFICIENT * _flexThetaRunningAverageRight + (1.0f - SMOOTHING_COEFFICIENT) * flexTheta; _ulnarRadialThetaRunningAverageRight = ulnarDeviationTheta; } - //get the flex/extension of the wrist rotation - glm::quat flex; - glm::quat nonFlex; - swingTwistDecomposition(relativeHandRotation, Vectors::UNIT_X, nonFlex, flex); - if (flex.w < 0.0f) { - flex *= 1.0f; - } - glm::vec3 flexAxis = glm::axis(flex); - float flexTheta = glm::sign(flexAxis[0]) * glm::angle(flex); - - if (left) { - if (glm::sign(flexTheta) != glm::sign(_flexThetaRunningAverageLeft) && fabsf(flexTheta) > (PI / 2.0f)) { - // don't allow the theta to cross the 180 degree limit. - flexTheta = -1.0f * flexTheta; - } - // put some smoothing on the theta - _flexThetaRunningAverageLeft = 0.5f * _flexThetaRunningAverageLeft + 0.5f * flexTheta; - } else { - if (glm::sign(flexTheta) != glm::sign(_flexThetaRunningAverageRight) && fabsf(flexTheta) > (PI / 2.0f)) { - // don't allow the theta to cross the 180 degree limit. - flexTheta = -1.0f * flexTheta; - } - // put some smoothing on the theta - _flexThetaRunningAverageRight = 0.5f * _flexThetaRunningAverageRight + 0.5f * flexTheta; - } - - glm::quat twist; - glm::quat nonTwist; - swingTwistDecomposition(relativeHandRotation, Vectors::UNIT_Y, nonTwist, twist); - if (twist.w < 0.0f) { - twist *= 1.0f; - } - glm::vec3 trueTwistAxis = glm::axis(twist); - float trueTwistTheta = glm::sign(trueTwistAxis[1]) * glm::angle(twist); - if (left) { - if (glm::sign(trueTwistTheta) != glm::sign(_twistThetaRunningAverageLeft) && fabsf(trueTwistTheta) > (PI / 2.0f)) { - // don't allow the theta to cross the 180 degree limit. - trueTwistTheta = -1.0f * trueTwistTheta; - } - // put some smoothing on the theta - _twistThetaRunningAverageLeft = 0.5f * _twistThetaRunningAverageLeft + 0.5f * trueTwistTheta; - } else { - if (glm::sign(trueTwistTheta) != glm::sign(_twistThetaRunningAverageRight) && fabsf(trueTwistTheta) > (PI / 2.0f)) { - // don't allow the theta to cross the 180 degree limit. - trueTwistTheta = -1.0f * trueTwistTheta; - } - // put some smoothing on the theta - _twistThetaRunningAverageRight = 0.5f * _twistThetaRunningAverageRight + 0.5f * trueTwistTheta; - } - + // get the correction angle for each axis and add it to the base pole vector theta float currentWristCoefficient = 0.0f; - if (left) { - currentWristCoefficient += computeUlnarRadialCompensation(_ulnarRadialThetaRunningAverageLeft, _twistThetaRunningAverageLeft, left); currentWristCoefficient += computeTwistCompensation(_twistThetaRunningAverageLeft, left); currentWristCoefficient += computeFlexCompensation(_flexThetaRunningAverageLeft, left); + //currentWristCoefficient += computeUlnarRadialCompensation(_ulnarRadialThetaRunningAverageLeft, _twistThetaRunningAverageLeft, left); } else { - currentWristCoefficient += computeUlnarRadialCompensation(_ulnarRadialThetaRunningAverageRight, _twistThetaRunningAverageRight, left); currentWristCoefficient += computeTwistCompensation(_twistThetaRunningAverageRight, left); currentWristCoefficient += computeFlexCompensation(_flexThetaRunningAverageRight, left); + //currentWristCoefficient += computeUlnarRadialCompensation(_ulnarRadialThetaRunningAverageRight, _twistThetaRunningAverageRight, left); } - - // i think limit theta here so we don't subtract more than is possible from last theta. - // actually theta is limited. to what though? - float theta = 0.0f; + + // find the previous contribution of the wrist and add the current wrist correction to it if (left) { _lastWristCoefficientLeft = _lastThetaLeft - _lastPositionThetaLeft; _lastWristCoefficientLeft += currentWristCoefficient; _lastPositionThetaLeft = positionalTheta; - theta = positionalTheta + _lastWristCoefficientLeft; - if (theta > 0.0f) { - theta = 0.0f; - } - //qCDebug(animation) << "theta " << theta << " lastThetaLeft " << _lastThetaLeft << "last position theta left"<<_lastPositionThetaLeft << "last wrist coeff " << _lastWristCoefficientLeft; + _lastThetaLeft = positionalTheta + _lastWristCoefficientLeft; } else { _lastWristCoefficientRight = _lastThetaRight - _lastPositionThetaRight; _lastWristCoefficientRight += currentWristCoefficient; _lastPositionThetaRight = positionalTheta; - theta += positionalTheta + _lastWristCoefficientRight; - if (theta < 0.0f) { - theta = 0.0f; - } + _lastThetaRight = positionalTheta + _lastWristCoefficientRight; } - if (!left) { - // qCDebug(animation) << "theta " << theta << "Last wrist" << _lastWristCoefficientRight << " flex ave: " << (_flexThetaRunningAverageRight / PI) * 180.0f << " twist ave: " << (_twistThetaRunningAverageRight/ PI) * 180.0f << " ulnar deviation ave: " << (_ulnarRadialThetaRunningAverageRight / PI) * 180.0f; + if (left) { + qCDebug(animation) << " ulnar deviation ave: " << (_ulnarRadialThetaRunningAverageLeft / PI) * 180.0f << " ulnar correction " << currentWristCoefficient << " twist theta " << (trueTwistTheta / PI) * 180.0f; } - // global limiting + // limit the correction anatomically possible angles and change to radians + const float LOWER_ANATOMICAL_ANGLE = 175.0f; + const float UPPER_ANATOMICAL_ANGLE = 50.0f; float thetaRadians = 0.0f; if (left) { - // final global smoothing - //_lastThetaLeft = 0.5f * _lastThetaLeft + 0.5f * theta; - _lastThetaLeft = theta; if (_lastThetaLeft > -50.0f) { _lastThetaLeft = -50.0f; } - if (_lastThetaLeft < -175.0f) { - _lastThetaLeft = -175.0f; + if (_lastThetaLeft < -LOWER_ANATOMICAL_ANGLE) { + _lastThetaLeft = -LOWER_ANATOMICAL_ANGLE; } const float MIN_VALUE = 0.0001f; if (fabsf(_lastPositionThetaLeft - _lastThetaLeft) > MIN_VALUE) { - qCDebug(animation) << "theta " << theta << " lastThetaLeft " << _lastThetaLeft << "last position theta left" << _lastPositionThetaLeft << "last wrist coeff " << _lastWristCoefficientLeft; + //qCDebug(animation) << " lastThetaLeft " << _lastThetaLeft << "last position theta left" << _lastPositionThetaLeft << "last wrist coeff " << _lastWristCoefficientLeft; } // convert to radians and make 180 0 to match pole vector theta thetaRadians = ((180.0f - _lastThetaLeft) / 180.0f)*PI; } else { - // final global smoothing - _lastThetaRight = theta; // 0.5f * _lastThetaRight + 0.5f * theta; - - if (_lastThetaRight < 50.0f) { - _lastThetaRight = 50.0f; + if (_lastThetaRight < UPPER_ANATOMICAL_ANGLE) { + _lastThetaRight = UPPER_ANATOMICAL_ANGLE; } - if (_lastThetaRight > 175.0f) { - _lastThetaRight = 175.0f; + if (_lastThetaRight > LOWER_ANATOMICAL_ANGLE) { + _lastThetaRight = LOWER_ANATOMICAL_ANGLE; } // convert to radians and make 180 0 to match pole vector theta thetaRadians = ((180.0f - _lastThetaRight) / 180.0f)*PI; } - float xValue = -1.0f * sin(thetaRadians); - float yValue = -1.0f * cos(thetaRadians); - float zValue = 0.0f; - glm::vec3 thetaVector(xValue, yValue, zValue); + // convert the final theta to a pole vector value + float poleVectorXValue = -1.0f * sin(thetaRadians); + float poleVectorYValue = -1.0f * cos(thetaRadians); + float poleVectorZValue = 0.0f; + glm::vec3 thetaVector(poleVectorXValue, poleVectorYValue, poleVectorZValue); glm::vec3 up = Vectors::UNIT_Y; glm::vec3 fwd = armToHand/glm::length(armToHand); From 27bfe2f0fe1dbfbb5e5c2bfb967ec026ea8d3649 Mon Sep 17 00:00:00 2001 From: amantley Date: Wed, 20 Feb 2019 15:14:12 -0800 Subject: [PATCH 096/112] changed name of pre processor variable --- interface/src/avatar/MyAvatar.cpp | 3 +- .../src/AnimPoleVectorConstraint.cpp | 4 -- libraries/animation/src/Rig.cpp | 49 ++++--------------- 3 files changed, 10 insertions(+), 46 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index c2e7292a0a..8ae59ebdc1 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -2943,7 +2943,6 @@ void MyAvatar::setAnimGraphUrl(const QUrl& url) { connect(&(_skeletonModel->getRig()), SIGNAL(onLoadComplete()), this, SLOT(animGraphLoaded())); } -#define USE_Q_OS_ANDROID void MyAvatar::initAnimGraph() { QUrl graphUrl; if (!_prefOverrideAnimGraphUrl.get().isEmpty()) { @@ -2953,7 +2952,7 @@ void MyAvatar::initAnimGraph() { } else { graphUrl = PathUtils::resourcesUrl("avatar/avatar-animation.json"); - #if defined(Q_OS_ANDROID) || defined(USE_Q_OS_ANDROID) + #if defined(Q_OS_ANDROID) || defined(HIFI_USE_Q_OS_ANDROID) graphUrl = PathUtils::resourcesUrl("avatar/avatar-animation_withSplineIKNode.json"); #endif } diff --git a/libraries/animation/src/AnimPoleVectorConstraint.cpp b/libraries/animation/src/AnimPoleVectorConstraint.cpp index 36c58ecb4e..c0600ee253 100644 --- a/libraries/animation/src/AnimPoleVectorConstraint.cpp +++ b/libraries/animation/src/AnimPoleVectorConstraint.cpp @@ -123,10 +123,6 @@ const AnimPoseVec& AnimPoleVectorConstraint::evaluate(const AnimVariantMap& anim glm::quat deltaRot = glm::angleAxis(theta, unitAxis); - if (_tipJointName == "RightHand") { - //qCDebug(animation) << "anim ik theta " << (theta / PI)*180.0f; - } - // transform result back into parent relative frame. glm::quat relBaseRot = glm::inverse(baseParentPose.rot()) * deltaRot * basePose.rot(); ikChain.setRelativePoseAtJointIndex(_baseJointIndex, AnimPose(relBaseRot, underPoses[_baseJointIndex].trans())); diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index 7273ccf637..2681777594 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -34,7 +34,6 @@ #include "IKTarget.h" #include "PathUtils.h" -#define USE_Q_OS_ANDROID static int nextRigId = 1; static std::map rigRegistry; static std::mutex rigRegistryMutex; @@ -1460,7 +1459,7 @@ void Rig::updateHands(bool leftHandEnabled, bool rightHandEnabled, bool hipsEnab int oppositeArmJointIndex = _animSkeleton->nameToJointIndex("RightArm"); if (ENABLE_POLE_VECTORS && handJointIndex >= 0 && armJointIndex >= 0 && elbowJointIndex >= 0 && oppositeArmJointIndex >= 0) { glm::vec3 poleVector; -#if defined(Q_OS_ANDROID) || defined(USE_Q_OS_ANDROID) +#if defined(Q_OS_ANDROID) || defined(HIFI_USE_Q_OS_ANDROID) bool isLeft = true; bool usePoleVector = calculateElbowPoleVectorOptimized(handJointIndex, elbowJointIndex, armJointIndex, isLeft, poleVector); #else @@ -1520,7 +1519,7 @@ void Rig::updateHands(bool leftHandEnabled, bool rightHandEnabled, bool hipsEnab if (ENABLE_POLE_VECTORS && handJointIndex >= 0 && armJointIndex >= 0 && elbowJointIndex >= 0 && oppositeArmJointIndex >= 0) { glm::vec3 poleVector; -#if defined(Q_OS_ANDROID) || defined(USE_Q_OS_ANDROID) +#if defined(Q_OS_ANDROID) || defined(HIFI_USE_Q_OS_ANDROID) bool isLeft = false; bool usePoleVector = calculateElbowPoleVectorOptimized(handJointIndex, elbowJointIndex, armJointIndex, isLeft, poleVector); #else @@ -1702,7 +1701,6 @@ static float getHandPositionTheta(glm::vec3 armToHand, float defaultArmLength, b const float zWeightBottom = -100.0f; const glm::vec3 weights(-50.0f, 60.0f, 90.0f); - float yFactor = (fabsf(armToHand[1] / defaultArmLength) * weights[1]) + biases[1]; float zFactor; @@ -1714,7 +1712,6 @@ static float getHandPositionTheta(glm::vec3 armToHand, float defaultArmLength, b float xFactor; if (left) { - //xFactor = weights[0] * glm::max(-1.0f * (armToHand[0] / defaultArmLength) + xStart, 0.0f); xFactor = weights[0] * ((-1.0f * (armToHand[0] / defaultArmLength) + xStart) - (0.2f) * ((1.0f + (armToHand[1] / defaultArmLength)) / 2.0f)); } else { xFactor = weights[0] * (((armToHand[0] / defaultArmLength) + xStart) - (0.2f) * ((1.0f + (armToHand[1] / defaultArmLength)) / 2.0f)); @@ -1722,18 +1719,19 @@ static float getHandPositionTheta(glm::vec3 armToHand, float defaultArmLength, b handPositionTheta = xFactor + yFactor + zFactor; - if (handPositionTheta < 50.0f) { - handPositionTheta = 50.0f; + const float LOWER_ANATOMICAL_ANGLE = 175.0f; + const float UPPER_ANATOMICAL_ANGLE = 50.0f; + if (handPositionTheta < LOWER_ANATOMICAL_ANGLE) { + handPositionTheta = LOWER_ANATOMICAL_ANGLE; } - if (handPositionTheta > 175.0f) { - handPositionTheta = 175.0f; + if (handPositionTheta > UPPER_ANATOMICAL_ANGLE) { + handPositionTheta = UPPER_ANATOMICAL_ANGLE; } if (left) { handPositionTheta *= -1.0f; } - return handPositionTheta; } @@ -1875,31 +1873,10 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s } else { unitAxis = Vectors::UNIT_Y; } - + // get the pole vector theta based on the hand position relative to the shoulder. float positionalTheta = getHandPositionTheta(armToHand, defaultArmLength, left); - //qCDebug(animation) << "hand position theta " << left << " " << positionalTheta; - /* - float deltaTheta = 0.0f; - if (left) { - deltaTheta = positionalTheta - _lastThetaLeft; - } else { - deltaTheta = positionalTheta - _lastThetaRight; - } - float deltaThetaRadians = (deltaTheta / 180.0f)*PI; - AnimPose deltaRot(glm::angleAxis(deltaThetaRadians, unitAxis), glm::vec3()); - AnimPose relMid = shoulderPose.inverse() * elbowPose; - AnimPose updatedBase = shoulderPose * deltaRot; - AnimPose newAbsMid = updatedBase * relMid; - - glm::quat axisRotation; - glm::quat nonAxisRotation; - swingTwistDecomposition(updatedBase.rot(), unitAxis, nonAxisRotation, axisRotation); - //qCDebug(animation) << "the rotation about the axis of the arm " << (glm::sign(glm::axis(axisRotation)[2]) * glm::angle(axisRotation) / PI)*180.0f << " delta Rot theta " << deltaTheta; - - //glm::quat relativeHandRotation = (newAbsMid.inverse() * handPose).rot(); - */ // now we calculate the contribution of the hand rotation relative to the arm glm::quat relativeHandRotation = (elbowPose.inverse() * handPose).rot(); @@ -1983,10 +1960,6 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s _lastPositionThetaRight = positionalTheta; _lastThetaRight = positionalTheta + _lastWristCoefficientRight; } - - if (left) { - qCDebug(animation) << " ulnar deviation ave: " << (_ulnarRadialThetaRunningAverageLeft / PI) * 180.0f << " ulnar correction " << currentWristCoefficient << " twist theta " << (trueTwistTheta / PI) * 180.0f; - } // limit the correction anatomically possible angles and change to radians const float LOWER_ANATOMICAL_ANGLE = 175.0f; @@ -2000,10 +1973,6 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s if (_lastThetaLeft < -LOWER_ANATOMICAL_ANGLE) { _lastThetaLeft = -LOWER_ANATOMICAL_ANGLE; } - const float MIN_VALUE = 0.0001f; - if (fabsf(_lastPositionThetaLeft - _lastThetaLeft) > MIN_VALUE) { - //qCDebug(animation) << " lastThetaLeft " << _lastThetaLeft << "last position theta left" << _lastPositionThetaLeft << "last wrist coeff " << _lastWristCoefficientLeft; - } // convert to radians and make 180 0 to match pole vector theta thetaRadians = ((180.0f - _lastThetaLeft) / 180.0f)*PI; } else { From 97da20781e1d4abcb68ad2a8cba34fd4ea1f5593 Mon Sep 17 00:00:00 2001 From: amantley Date: Wed, 20 Feb 2019 15:19:36 -0800 Subject: [PATCH 097/112] removed whitespace --- libraries/animation/src/Rig.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index 2681777594..ac026d192f 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -1757,7 +1757,7 @@ static float computeUlnarRadialCompensation(float ulnarRadialTheta, float twistT } if (fabsf(ulnarDiff) > 0.0f) { float twistCoefficient = 0.0f; - + if (left) { twistCoefficient = twistTheta; if (twistCoefficient > (PI / 6.0f)) { @@ -1774,7 +1774,7 @@ static float computeUlnarRadialCompensation(float ulnarRadialTheta, float twistT } } - + if (twistTheta < 0.0f) { if (left) { ulnarCorrection -= glm::sign(ulnarDiff) * (fabsf(ulnarDiff) / PI) * 180.0f * twistCoefficient; @@ -1803,7 +1803,7 @@ static float computeTwistCompensation(float twistTheta, bool left) { const float TWIST_DEADZONE = PI / 2.0f; float twistCorrection = 0.0f; - + if (fabsf(twistTheta) > TWIST_DEADZONE) { twistCorrection = glm::sign(twistTheta) * ((fabsf(twistTheta) - TWIST_DEADZONE) / PI) * 90.0f; } @@ -1821,7 +1821,7 @@ static float computeFlexCompensation(float flexTheta, bool left) { const float EXTEND_BOUNDARY = -PI / 4.0f; float flexCorrection = 0.0f; float currentWristCoefficient = 0.0f; - + if (flexTheta > FLEX_BOUNDARY) { flexCorrection = ((flexTheta - FLEX_BOUNDARY) / PI) * 60.0f; } else if (flexTheta < EXTEND_BOUNDARY) { From f8a74efdc247cb6f2f57f0b1c97f91591b56c0fa Mon Sep 17 00:00:00 2001 From: amantley Date: Wed, 20 Feb 2019 17:59:45 -0800 Subject: [PATCH 098/112] fixed build errors from jenkins --- CMakeLists.txt | 5 +++++ interface/src/avatar/MySkeletonModel.cpp | 2 -- libraries/animation/src/AnimSplineIK.cpp | 3 --- libraries/animation/src/Rig.cpp | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c8710eed05..045234ebe1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -236,6 +236,11 @@ if (BUILD_TESTS) endif() endif() +set(HIFI_USE_Q_OS_ANDROID=TRUE) +if (HIFI_USE_Q_OS_ANDROID) + add_definitions(-DHIFI_USE_Q_OS_ANDROID=TRUE) +endif() + if (BUILD_INSTALLER) if (UNIX) install( diff --git a/interface/src/avatar/MySkeletonModel.cpp b/interface/src/avatar/MySkeletonModel.cpp index 32a8e1e38d..5837e0a84c 100755 --- a/interface/src/avatar/MySkeletonModel.cpp +++ b/interface/src/avatar/MySkeletonModel.cpp @@ -15,8 +15,6 @@ #include "InterfaceLogging.h" #include "AnimUtil.h" -#define USE_Q_OS_ANDROID - MySkeletonModel::MySkeletonModel(Avatar* owningAvatar, QObject* parent) : SkeletonModel(owningAvatar, parent) { } diff --git a/libraries/animation/src/AnimSplineIK.cpp b/libraries/animation/src/AnimSplineIK.cpp index 30e0a42e65..cfb34560ff 100644 --- a/libraries/animation/src/AnimSplineIK.cpp +++ b/libraries/animation/src/AnimSplineIK.cpp @@ -362,7 +362,6 @@ void AnimSplineIK::solveTargetWithSpline(const AnimContext& context, int base, c AnimPose relPose = parentAbsPose.inverse() * flexedAbsPose; - bool constrained = false; if (splineJointInfo.jointIndex != base) { // constrain the amount the spine can stretch or compress float length = glm::length(relPose.trans()); @@ -374,10 +373,8 @@ void AnimSplineIK::solveTargetWithSpline(const AnimContext& context, int base, c const float MIN_LENGTH = defaultLength * (1.0f - STRETCH_COMPRESS_PERCENTAGE); if (length > MAX_LENGTH) { relPose.trans() = (relPose.trans() / length) * MAX_LENGTH; - constrained = true; } else if (length < MIN_LENGTH) { relPose.trans() = (relPose.trans() / length) * MIN_LENGTH; - constrained = true; } } else { relPose.trans() = glm::vec3(0.0f); diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index ac026d192f..9139776612 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -1988,8 +1988,8 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s } // convert the final theta to a pole vector value - float poleVectorXValue = -1.0f * sin(thetaRadians); - float poleVectorYValue = -1.0f * cos(thetaRadians); + float poleVectorXValue = -1.0f * sinf(thetaRadians); + float poleVectorYValue = -1.0f * cosf(thetaRadians); float poleVectorZValue = 0.0f; glm::vec3 thetaVector(poleVectorXValue, poleVectorYValue, poleVectorZValue); From b6bc467f4b66702e8cbafbe08b697ae448f5d650 Mon Sep 17 00:00:00 2001 From: Angus Antley Date: Thu, 21 Feb 2019 06:42:55 -0800 Subject: [PATCH 099/112] added HIFI_USE_Q_OS_ANDROID to cmake lists and to MySkeletonModel --- CMakeLists.txt | 15 +++++++++------ interface/src/avatar/MySkeletonModel.cpp | 4 ++-- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 045234ebe1..5bd4d4620b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -52,6 +52,7 @@ else() set(MOBILE 0) endif() +set(HIFI_USE_Q_OS_ANDROID_OPTION OFF) set(BUILD_CLIENT_OPTION ON) set(BUILD_SERVER_OPTION ON) set(BUILD_TESTS_OPTION OFF) @@ -108,7 +109,7 @@ if (USE_GLES AND (NOT ANDROID)) set(DISABLE_QML_OPTION ON) endif() - +option(HIFI_USE_Q_OS_ANDROID "USE OPTIMIZED IK" ${HIFI_USE_Q_OS_ANDROID_OPTION}) option(BUILD_CLIENT "Build client components" ${BUILD_CLIENT_OPTION}) option(BUILD_SERVER "Build server components" ${BUILD_SERVER_OPTION}) option(BUILD_TESTS "Build tests" ${BUILD_TESTS_OPTION}) @@ -139,6 +140,7 @@ foreach(PLATFORM_QT_COMPONENT ${PLATFORM_QT_COMPONENTS}) list(APPEND PLATFORM_QT_LIBRARIES "Qt5::${PLATFORM_QT_COMPONENT}") endforeach() +MESSAGE(STATUS "USE OPTIMIZED IK: " ${HIFI_USE_Q_OS_ANDROID}) MESSAGE(STATUS "Build server: " ${BUILD_SERVER}) MESSAGE(STATUS "Build client: " ${BUILD_CLIENT}) MESSAGE(STATUS "Build tests: " ${BUILD_TESTS}) @@ -184,6 +186,12 @@ find_package( Threads ) add_definitions(-DGLM_FORCE_RADIANS) add_definitions(-DGLM_ENABLE_EXPERIMENTAL) add_definitions(-DGLM_FORCE_CTOR_INIT) +#add_definitions(-DHIFI_USE_Q_OS_ANDROID) +#option(HIFI_USE_Q_OS_ANDROID_OPTION "hifi_use_optimized_ik" OFF) +if (HIFI_USE_Q_OS_ANDROID) + MESSAGE(STATUS "SET THE USE IK DEFINITION ") + add_definitions(-DHIFI_USE_Q_OS_ANDROID) +endif() set(HIFI_LIBRARY_DIR "${CMAKE_CURRENT_SOURCE_DIR}/libraries") set(EXTERNAL_PROJECT_PREFIX "project") @@ -236,11 +244,6 @@ if (BUILD_TESTS) endif() endif() -set(HIFI_USE_Q_OS_ANDROID=TRUE) -if (HIFI_USE_Q_OS_ANDROID) - add_definitions(-DHIFI_USE_Q_OS_ANDROID=TRUE) -endif() - if (BUILD_INSTALLER) if (UNIX) install( diff --git a/interface/src/avatar/MySkeletonModel.cpp b/interface/src/avatar/MySkeletonModel.cpp index 5837e0a84c..86a0dceae0 100755 --- a/interface/src/avatar/MySkeletonModel.cpp +++ b/interface/src/avatar/MySkeletonModel.cpp @@ -250,7 +250,7 @@ void MySkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) { AnimPose headAvatarSpace(avatarHeadPose.getRotation(), avatarHeadPose.getTranslation()); AnimPose headRigSpace = avatarToRigPose * headAvatarSpace; AnimPose hipsRigSpace = sensorToRigPose * sensorHips; -#if defined(Q_OS_ANDROID) || defined(USE_Q_OS_ANDROID) +#if defined(Q_OS_ANDROID) || defined(HIFI_USE_Q_OS_ANDROID) glm::vec3 spine2TargetTranslation = computeSpine2WithHeadHipsSpline(myAvatar, hipsRigSpace, headRigSpace); #endif const float SPINE2_ROTATION_FILTER = 0.5f; @@ -274,7 +274,7 @@ void MySkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) { } generateBasisVectors(up, fwd, u, v, w); AnimPose newSpinePose(glm::mat4(glm::vec4(w, 0.0f), glm::vec4(u, 0.0f), glm::vec4(v, 0.0f), glm::vec4(glm::vec3(0.0f, 0.0f, 0.0f), 1.0f))); -#if defined(Q_OS_ANDROID) || defined(USE_Q_OS_ANDROID) +#if defined(Q_OS_ANDROID) || defined(HIFI_USE_Q_OS_ANDROID) currentSpine2Pose.trans() = spine2TargetTranslation; #endif currentSpine2Pose.rot() = safeLerp(currentSpine2Pose.rot(), newSpinePose.rot(), SPINE2_ROTATION_FILTER); From 33fd64c68c908800ca24d569e244d08e23ba2f30 Mon Sep 17 00:00:00 2001 From: amantley Date: Thu, 21 Feb 2019 09:00:23 -0800 Subject: [PATCH 100/112] direction on compare in positional theta function --- libraries/animation/src/Rig.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index 9139776612..f2b4be077f 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -1721,10 +1721,10 @@ static float getHandPositionTheta(glm::vec3 armToHand, float defaultArmLength, b const float LOWER_ANATOMICAL_ANGLE = 175.0f; const float UPPER_ANATOMICAL_ANGLE = 50.0f; - if (handPositionTheta < LOWER_ANATOMICAL_ANGLE) { + if (handPositionTheta > LOWER_ANATOMICAL_ANGLE) { handPositionTheta = LOWER_ANATOMICAL_ANGLE; } - if (handPositionTheta > UPPER_ANATOMICAL_ANGLE) { + if (handPositionTheta < UPPER_ANATOMICAL_ANGLE) { handPositionTheta = UPPER_ANATOMICAL_ANGLE; } @@ -1876,7 +1876,9 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s // get the pole vector theta based on the hand position relative to the shoulder. float positionalTheta = getHandPositionTheta(armToHand, defaultArmLength, left); - + if (left) { + qCDebug(animation) << "positional theta left "<< positionalTheta; + } // now we calculate the contribution of the hand rotation relative to the arm glm::quat relativeHandRotation = (elbowPose.inverse() * handPose).rot(); From 4fdf556d5dc37bd62df39f7e4cd001a513a922de Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Thu, 21 Feb 2019 10:29:21 -0800 Subject: [PATCH 101/112] fix billboard mode in secondary camera --- interface/src/Application.cpp | 18 +++++++++--------- .../src/RenderableImageEntityItem.cpp | 2 +- .../src/RenderableTextEntityItem.cpp | 2 +- .../src/RenderableWebEntityItem.cpp | 2 +- libraries/entities/src/EntityItem.cpp | 3 ++- libraries/entities/src/EntityItem.h | 9 ++++++--- libraries/entities/src/ImageEntityItem.cpp | 2 +- libraries/entities/src/TextEntityItem.cpp | 2 +- libraries/entities/src/WebEntityItem.cpp | 2 +- 9 files changed, 23 insertions(+), 19 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index a611738445..83b287b7ae 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2301,31 +2301,31 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo DependencyManager::get()->setPrecisionPicking(rayPickID, value); }); - EntityItem::setBillboardRotationOperator([this](const glm::vec3& position, const glm::quat& rotation, BillboardMode billboardMode) { + EntityItem::setBillboardRotationOperator([this](const glm::vec3& position, const glm::quat& rotation, BillboardMode billboardMode, const glm::vec3& frustumPos) { if (billboardMode == BillboardMode::YAW) { //rotate about vertical to face the camera - ViewFrustum frustum; - copyViewFrustum(frustum); - glm::vec3 dPosition = frustum.getPosition() - position; + glm::vec3 dPosition = frustumPos - position; // If x and z are 0, atan(x, z) is undefined, so default to 0 degrees float yawRotation = dPosition.x == 0.0f && dPosition.z == 0.0f ? 0.0f : glm::atan(dPosition.x, dPosition.z); return glm::quat(glm::vec3(0.0f, yawRotation, 0.0f)); } else if (billboardMode == BillboardMode::FULL) { - ViewFrustum frustum; - copyViewFrustum(frustum); - glm::vec3 cameraPos = frustum.getPosition(); // use the referencial from the avatar, y isn't always up glm::vec3 avatarUP = DependencyManager::get()->getMyAvatar()->getWorldOrientation() * Vectors::UP; // check to see if glm::lookAt will work / using glm::lookAt variable name - glm::highp_vec3 s(glm::cross(position - cameraPos, avatarUP)); + glm::highp_vec3 s(glm::cross(position - frustumPos, avatarUP)); // make sure s is not NaN for any component if (glm::length2(s) > 0.0f) { - return glm::conjugate(glm::toQuat(glm::lookAt(cameraPos, position, avatarUP))); + return glm::conjugate(glm::toQuat(glm::lookAt(frustumPos, position, avatarUP))); } } return rotation; }); + EntityItem::setPrimaryViewFrustumPositionOperator([this]() { + ViewFrustum viewFrustum; + copyViewFrustum(viewFrustum); + return viewFrustum.getPosition(); + }); render::entities::WebEntityRenderer::setAcquireWebSurfaceOperator([this](const QString& url, bool htmlContent, QSharedPointer& webSurface, bool& cachedWebSurface) { bool isTablet = url == TabletScriptingInterface::QML; diff --git a/libraries/entities-renderer/src/RenderableImageEntityItem.cpp b/libraries/entities-renderer/src/RenderableImageEntityItem.cpp index 96dd1733e7..6638bc0687 100644 --- a/libraries/entities-renderer/src/RenderableImageEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableImageEntityItem.cpp @@ -170,7 +170,7 @@ void ImageEntityRenderer::doRender(RenderArgs* args) { Q_ASSERT(args->_batch); gpu::Batch* batch = args->_batch; - transform.setRotation(EntityItem::getBillboardRotation(transform.getTranslation(), transform.getRotation(), _billboardMode)); + transform.setRotation(EntityItem::getBillboardRotation(transform.getTranslation(), transform.getRotation(), _billboardMode, args->getViewFrustum().getPosition())); transform.postScale(dimensions); batch->setModelTransform(transform); diff --git a/libraries/entities-renderer/src/RenderableTextEntityItem.cpp b/libraries/entities-renderer/src/RenderableTextEntityItem.cpp index 99912e9d91..dfc9277bf0 100644 --- a/libraries/entities-renderer/src/RenderableTextEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableTextEntityItem.cpp @@ -181,7 +181,7 @@ void TextEntityRenderer::doRender(RenderArgs* args) { gpu::Batch& batch = *args->_batch; auto transformToTopLeft = modelTransform; - transformToTopLeft.setRotation(EntityItem::getBillboardRotation(transformToTopLeft.getTranslation(), transformToTopLeft.getRotation(), _billboardMode)); + transformToTopLeft.setRotation(EntityItem::getBillboardRotation(transformToTopLeft.getTranslation(), transformToTopLeft.getRotation(), _billboardMode, args->getViewFrustum().getPosition())); transformToTopLeft.postTranslate(dimensions * glm::vec3(-0.5f, 0.5f, 0.0f)); // Go to the top left transformToTopLeft.setScale(1.0f); // Use a scale of one so that the text is not deformed diff --git a/libraries/entities-renderer/src/RenderableWebEntityItem.cpp b/libraries/entities-renderer/src/RenderableWebEntityItem.cpp index bf7820fecd..ccd815b74a 100644 --- a/libraries/entities-renderer/src/RenderableWebEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableWebEntityItem.cpp @@ -323,7 +323,7 @@ void WebEntityRenderer::doRender(RenderArgs* args) { }); batch.setResourceTexture(0, _texture); - transform.setRotation(EntityItem::getBillboardRotation(transform.getTranslation(), transform.getRotation(), _billboardMode)); + transform.setRotation(EntityItem::getBillboardRotation(transform.getTranslation(), transform.getRotation(), _billboardMode, args->getViewFrustum().getPosition())); batch.setModelTransform(transform); // Turn off jitter for these entities diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index 9f11b3c018..a431c82390 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -49,7 +49,8 @@ int EntityItem::_maxActionsDataSize = 800; quint64 EntityItem::_rememberDeletedActionTime = 20 * USECS_PER_SECOND; QString EntityItem::_marketplacePublicKey; -std::function EntityItem::_getBillboardRotationOperator = [](const glm::vec3&, const glm::quat& rotation, BillboardMode) { return rotation; }; +std::function EntityItem::_getBillboardRotationOperator = [](const glm::vec3&, const glm::quat& rotation, BillboardMode, const glm::vec3&) { return rotation; }; +std::function EntityItem::_getPrimaryViewFrustumPositionOperator = []() { return glm::vec3(0.0f); }; EntityItem::EntityItem(const EntityItemID& entityItemID) : SpatiallyNestable(NestableType::Entity, entityItemID) diff --git a/libraries/entities/src/EntityItem.h b/libraries/entities/src/EntityItem.h index 824261c022..0ca851e228 100644 --- a/libraries/entities/src/EntityItem.h +++ b/libraries/entities/src/EntityItem.h @@ -557,8 +557,10 @@ public: virtual void removeGrab(GrabPointer grab) override; virtual void disableGrab(GrabPointer grab) override; - static void setBillboardRotationOperator(std::function getBillboardRotationOperator) { _getBillboardRotationOperator = getBillboardRotationOperator; } - static glm::quat getBillboardRotation(const glm::vec3& position, const glm::quat& rotation, BillboardMode billboardMode) { return _getBillboardRotationOperator(position, rotation, billboardMode); } + static void setBillboardRotationOperator(std::function getBillboardRotationOperator) { _getBillboardRotationOperator = getBillboardRotationOperator; } + static glm::quat getBillboardRotation(const glm::vec3& position, const glm::quat& rotation, BillboardMode billboardMode, const glm::vec3& frustumPos) { return _getBillboardRotationOperator(position, rotation, billboardMode, frustumPos); } + static void setPrimaryViewFrustumPositionOperator(std::function getPrimaryViewFrustumPositionOperator) { _getPrimaryViewFrustumPositionOperator = getPrimaryViewFrustumPositionOperator; } + static glm::vec3 getPrimaryViewFrustumPosition() { return _getPrimaryViewFrustumPositionOperator(); } signals: void requestRenderUpdate(); @@ -748,7 +750,8 @@ protected: QHash _grabActions; private: - static std::function _getBillboardRotationOperator; + static std::function _getBillboardRotationOperator; + static std::function _getPrimaryViewFrustumPositionOperator; }; #endif // hifi_EntityItem_h diff --git a/libraries/entities/src/ImageEntityItem.cpp b/libraries/entities/src/ImageEntityItem.cpp index 837e824f4a..090ae91277 100644 --- a/libraries/entities/src/ImageEntityItem.cpp +++ b/libraries/entities/src/ImageEntityItem.cpp @@ -159,7 +159,7 @@ bool ImageEntityItem::findDetailedRayIntersection(const glm::vec3& origin, const glm::vec2 xyDimensions(dimensions.x, dimensions.y); glm::quat rotation = getWorldOrientation(); glm::vec3 position = getWorldPosition() + rotation * (dimensions * (ENTITY_ITEM_DEFAULT_REGISTRATION_POINT - getRegistrationPoint())); - rotation = EntityItem::getBillboardRotation(position, rotation, _billboardMode); + rotation = EntityItem::getBillboardRotation(position, rotation, _billboardMode, EntityItem::getPrimaryViewFrustumPosition()); if (findRayRectangleIntersection(origin, direction, rotation, position, xyDimensions, distance)) { glm::vec3 forward = rotation * Vectors::FRONT; diff --git a/libraries/entities/src/TextEntityItem.cpp b/libraries/entities/src/TextEntityItem.cpp index bc98c61ff7..5dff645c89 100644 --- a/libraries/entities/src/TextEntityItem.cpp +++ b/libraries/entities/src/TextEntityItem.cpp @@ -199,7 +199,7 @@ bool TextEntityItem::findDetailedRayIntersection(const glm::vec3& origin, const glm::vec2 xyDimensions(dimensions.x, dimensions.y); glm::quat rotation = getWorldOrientation(); glm::vec3 position = getWorldPosition() + rotation * (dimensions * (ENTITY_ITEM_DEFAULT_REGISTRATION_POINT - getRegistrationPoint())); - rotation = EntityItem::getBillboardRotation(position, rotation, _billboardMode); + rotation = EntityItem::getBillboardRotation(position, rotation, _billboardMode, EntityItem::getPrimaryViewFrustumPosition()); if (findRayRectangleIntersection(origin, direction, rotation, position, xyDimensions, distance)) { glm::vec3 forward = rotation * Vectors::FRONT; diff --git a/libraries/entities/src/WebEntityItem.cpp b/libraries/entities/src/WebEntityItem.cpp index 5a948fbfd4..0748790df9 100644 --- a/libraries/entities/src/WebEntityItem.cpp +++ b/libraries/entities/src/WebEntityItem.cpp @@ -180,7 +180,7 @@ bool WebEntityItem::findDetailedRayIntersection(const glm::vec3& origin, const g glm::vec2 xyDimensions(dimensions.x, dimensions.y); glm::quat rotation = getWorldOrientation(); glm::vec3 position = getWorldPosition() + rotation * (dimensions * (ENTITY_ITEM_DEFAULT_REGISTRATION_POINT - getRegistrationPoint())); - rotation = EntityItem::getBillboardRotation(position, rotation, _billboardMode); + rotation = EntityItem::getBillboardRotation(position, rotation, _billboardMode, EntityItem::getPrimaryViewFrustumPosition()); if (findRayRectangleIntersection(origin, direction, rotation, position, xyDimensions, distance)) { glm::vec3 forward = rotation * Vectors::FRONT; From ec4d069011c6dea61029644222a22a10128d1fef Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Thu, 21 Feb 2019 12:00:19 -0700 Subject: [PATCH 102/112] Allow threads with only one joint, remove dummy joints and unused constants --- libraries/animation/src/Flow.cpp | 79 ++++++++++++++------------------ libraries/animation/src/Flow.h | 47 ++++++------------- libraries/animation/src/Rig.cpp | 11 ++--- 3 files changed, 54 insertions(+), 83 deletions(-) diff --git a/libraries/animation/src/Flow.cpp b/libraries/animation/src/Flow.cpp index 480ded2002..9fb0306fa3 100644 --- a/libraries/animation/src/Flow.cpp +++ b/libraries/animation/src/Flow.cpp @@ -252,6 +252,7 @@ void FlowJoint::setInitialData(const glm::vec3& initialPosition, const glm::vec3 _previousPosition = initialPosition; _currentPosition = initialPosition; _initialTranslation = initialTranslation; + _currentRotation = initialRotation; _initialRotation = initialRotation; _translationDirection = glm::normalize(_initialTranslation); _parentPosition = parentPosition; @@ -280,7 +281,7 @@ void FlowJoint::update(float deltaTime) { } FlowNode::update(deltaTime, accelerationOffset); if (_anchored) { - if (!_isDummy) { + if (!_isHelper) { _currentPosition = _updatedPosition; } else { _currentPosition = _parentPosition; @@ -301,19 +302,10 @@ void FlowJoint::solve(const FlowCollisionResult& collision) { FlowNode::solve(_parentPosition, _length, collision); }; -FlowDummyJoint::FlowDummyJoint(const glm::vec3& initialPosition, int index, int parentIndex, int childIndex, FlowPhysicsSettings settings) : - FlowJoint(index, parentIndex, childIndex, DUMMY_KEYWORD + "_" + index, DUMMY_KEYWORD, settings) { - _isDummy = true; +void FlowJoint::toHelperJoint(const glm::vec3& initialPosition, float length) { _initialPosition = initialPosition; - _length = DUMMY_JOINT_DISTANCE; -} - -void FlowDummyJoint::toIsolatedJoint(float length, int childIndex, const QString& group) { - _isDummy = false; + _isHelper = true; _length = length; - _childIndex = childIndex; - _group = group; - } FlowThread::FlowThread(int rootIndex, std::map* joints) { @@ -344,6 +336,7 @@ void FlowThread::computeFlowThread(int rootIndex) { break; } } + _length = 0.0f; for (size_t i = 0; i < indexes.size(); i++) { int index = indexes[i]; _joints.push_back(index); @@ -456,6 +449,7 @@ FlowThread& FlowThread::operator=(const FlowThread& otherFlowThread) { myJoint._updatedPosition = joint._updatedPosition; myJoint._updatedRotation = joint._updatedRotation; myJoint._updatedTranslation = joint._updatedTranslation; + myJoint._isHelper = joint._isHelper; } return *this; } @@ -532,9 +526,9 @@ void Flow::calculateConstraints(const std::shared_ptr& skeleton, glm::vec3 jointPosition, parentPosition, jointTranslation; glm::quat jointRotation; getJointPositionInWorldFrame(absolutePoses, jointIndex, jointPosition, _entityPosition, _entityRotation); - getJointPositionInWorldFrame(absolutePoses, jointData.second.getParentIndex(), parentPosition, _entityPosition, _entityRotation); getJointTranslation(relativePoses, jointIndex, jointTranslation); getJointRotation(relativePoses, jointIndex, jointRotation); + getJointPositionInWorldFrame(absolutePoses, jointData.second.getParentIndex(), parentPosition, _entityPosition, _entityRotation); jointData.second.setInitialData(jointPosition, jointTranslation, jointRotation, parentPosition); } @@ -549,47 +543,36 @@ void Flow::calculateConstraints(const std::shared_ptr& skeleton, _flowJointData[joint.second.getParentIndex()].setChildIndex(joint.first); } } - + int extraIndex = -1; for (size_t i = 0; i < roots.size(); i++) { FlowThread thread = FlowThread(roots[i], &_flowJointData); // add threads with at least 2 joints if (thread._joints.size() > 0) { if (thread._joints.size() == 1) { int jointIndex = roots[i]; - auto joint = _flowJointData[jointIndex]; - auto jointPosition = joint.getUpdatedPosition(); - auto newSettings = FlowPhysicsSettings(joint.getSettings()); - newSettings._stiffness = ISOLATED_JOINT_STIFFNESS; - int extraIndex = (int)_flowJointData.size(); - auto newJoint = FlowDummyJoint(jointPosition, extraIndex, jointIndex, -1, newSettings); - newJoint.toIsolatedJoint(ISOLATED_JOINT_LENGTH, extraIndex, _flowJointData[jointIndex].getGroup()); - thread = FlowThread(jointIndex, &_flowJointData); + auto &joint = _flowJointData[jointIndex]; + auto &jointPosition = joint.getUpdatedPosition(); + auto newSettings = joint.getSettings(); + extraIndex = extraIndex > -1 ? extraIndex + 1 : skeleton->getNumJoints(); + joint.setChildIndex(extraIndex); + auto newJoint = FlowJoint(extraIndex, jointIndex, -1, joint.getName(), joint.getGroup(), newSettings); + newJoint.toHelperJoint(jointPosition, HELPER_JOINT_LENGTH); + glm::vec3 translation = glm::vec3(0.0f, HELPER_JOINT_LENGTH, 0.0f); + newJoint.setInitialData(jointPosition + translation, 100.0f * translation , Quaternions::IDENTITY, jointPosition); + _flowJointData.insert(std::pair(extraIndex, newJoint)); + FlowThread newThread = FlowThread(jointIndex, &_flowJointData); + if (newThread._joints.size() > 1) { + _jointThreads.push_back(newThread); + } + } else { + _jointThreads.push_back(thread); } - _jointThreads.push_back(thread); } } if (_jointThreads.size() == 0) { onCleanup(); } - if (SHOW_DUMMY_JOINTS && rightHandIndex > -1) { - int jointCount = (int)_flowJointData.size(); - int extraIndex = (int)_flowJointData.size(); - glm::vec3 rightHandPosition; - getJointPositionInWorldFrame(absolutePoses, rightHandIndex, rightHandPosition, _entityPosition, _entityRotation); - int parentIndex = rightHandIndex; - for (int i = 0; i < DUMMY_JOINT_COUNT; i++) { - int childIndex = (i == (DUMMY_JOINT_COUNT - 1)) ? -1 : extraIndex + 1; - auto newJoint = FlowDummyJoint(rightHandPosition, extraIndex, parentIndex, childIndex, DEFAULT_JOINT_SETTINGS); - _flowJointData.insert(std::pair(extraIndex, newJoint)); - parentIndex = extraIndex; - extraIndex++; - } - _flowJointData[jointCount].setAnchored(true); - - auto extraThread = FlowThread(jointCount, &_flowJointData); - _jointThreads.push_back(extraThread); - } if (handsIndices.size() > 0) { FlowCollisionSettings handSettings; handSettings._radius = HAND_COLLISION_RADIUS; @@ -699,10 +682,16 @@ void Flow::updateJoints(AnimPoseVec& relativePoses, AnimPoseVec& absolutePoses) int jointIndex = jointData.first; glm::vec3 jointPosition, parentPosition, jointTranslation; glm::quat jointRotation, parentWorldRotation; - getJointPositionInWorldFrame(absolutePoses, jointIndex, jointPosition, _entityPosition, _entityRotation); + if (!jointData.second.isHelper()) { + getJointPositionInWorldFrame(absolutePoses, jointIndex, jointPosition, _entityPosition, _entityRotation); + getJointTranslation(relativePoses, jointIndex, jointTranslation); + getJointRotation(relativePoses, jointIndex, jointRotation); + } else { + jointPosition = jointData.second.getCurrentPosition(); + jointTranslation = jointData.second.getCurrentTranslation(); + jointRotation = jointData.second.getCurrentRotation(); + } getJointPositionInWorldFrame(absolutePoses, jointData.second.getParentIndex(), parentPosition, _entityPosition, _entityRotation); - getJointTranslation(relativePoses, jointIndex, jointTranslation); - getJointRotation(relativePoses, jointIndex, jointRotation); getJointRotationInWorldFrame(absolutePoses, jointData.second.getParentIndex(), parentWorldRotation, _entityRotation); jointData.second.setUpdatedData(jointPosition, jointTranslation, jointRotation, parentPosition, parentWorldRotation); } @@ -753,7 +742,7 @@ bool Flow::getJointPositionInWorldFrame(const AnimPoseVec& absolutePoses, int jo } else { position = glm::vec3(0.0f); } - } + } return false; } diff --git a/libraries/animation/src/Flow.h b/libraries/animation/src/Flow.h index 5fe7b7acbc..35464e9420 100644 --- a/libraries/animation/src/Flow.h +++ b/libraries/animation/src/Flow.h @@ -23,11 +23,6 @@ class Rig; class AnimSkeleton; -const bool SHOW_DUMMY_JOINTS = false; - -const int LEFT_HAND = 0; -const int RIGHT_HAND = 1; - const float HAPTIC_TOUCH_STRENGTH = 0.25f; const float HAPTIC_TOUCH_DURATION = 10.0f; const float HAPTIC_SLOPE = 0.18f; @@ -38,19 +33,8 @@ const QString SIM_JOINT_PREFIX = "sim"; const std::vector HAND_COLLISION_JOINTS = { "RightHandMiddle1", "RightHandThumb3", "LeftHandMiddle1", "LeftHandThumb3", "RightHandMiddle3", "LeftHandMiddle3" }; -const QString JOINT_COLLISION_PREFIX = "joint_"; -const QString HAND_COLLISION_PREFIX = "hand_"; const float HAND_COLLISION_RADIUS = 0.03f; -const float HAND_TOUCHING_DISTANCE = 2.0f; - -const int COLLISION_SHAPES_LIMIT = 4; - -const QString DUMMY_KEYWORD = "Extra"; -const int DUMMY_JOINT_COUNT = 8; -const float DUMMY_JOINT_DISTANCE = 0.05f; - -const float ISOLATED_JOINT_STIFFNESS = 0.0f; -const float ISOLATED_JOINT_LENGTH = 0.05f; +const float HELPER_JOINT_LENGTH = 0.05f; const float DEFAULT_STIFFNESS = 0.0f; const float DEFAULT_GRAVITY = -0.0096f; @@ -212,6 +196,7 @@ public: FlowJoint(): FlowNode() {}; FlowJoint(int jointIndex, int parentIndex, int childIndex, const QString& name, const QString& group, const FlowPhysicsSettings& settings); + void toHelperJoint(const glm::vec3& initialPosition, float length); void setInitialData(const glm::vec3& initialPosition, const glm::vec3& initialTranslation, const glm::quat& initialRotation, const glm::vec3& parentPosition); void setUpdatedData(const glm::vec3& updatedPosition, const glm::vec3& updatedTranslation, const glm::quat& updatedRotation, const glm::vec3& parentPosition, const glm::quat& parentWorldRotation); void setRecoveryPosition(const glm::vec3& recoveryPosition); @@ -219,19 +204,23 @@ public: void solve(const FlowCollisionResult& collision); void setScale(float scale, bool initScale); - bool isAnchored() { return _anchored; } + bool isAnchored() const { return _anchored; } void setAnchored(bool anchored) { _anchored = anchored; } + bool isHelper() const { return _isHelper; } const FlowPhysicsSettings& getSettings() { return _settings; } void setSettings(const FlowPhysicsSettings& settings) { _settings = settings; } - const glm::vec3& getCurrentPosition() { return _currentPosition; } - int getIndex() { return _index; } - int getParentIndex() { return _parentIndex; } + const glm::vec3& getCurrentPosition() const { return _currentPosition; } + int getIndex() const { return _index; } + int getParentIndex() const { return _parentIndex; } void setChildIndex(int index) { _childIndex = index; } - const glm::vec3& getUpdatedPosition() { return _updatedPosition; } - const QString& getGroup() { return _group; } - const glm::quat& getCurrentRotation() { return _currentRotation; } + const glm::vec3& getUpdatedPosition() const { return _updatedPosition; } + const QString& getGroup() const { return _group; } + const QString& getName() const { return _name; } + const glm::quat& getCurrentRotation() const { return _currentRotation; } + const glm::vec3& getCurrentTranslation() const { return _initialTranslation; } + const glm::vec3& getInitialPosition() const { return _initialPosition; } protected: @@ -240,7 +229,8 @@ protected: int _childIndex{ -1 }; QString _name; QString _group; - bool _isDummy{ false }; + + bool _isHelper{ false }; glm::vec3 _initialTranslation; glm::quat _initialRotation; @@ -262,13 +252,6 @@ protected: bool _applyRecovery { false }; }; -class FlowDummyJoint : public FlowJoint { -public: - FlowDummyJoint(const glm::vec3& initialPosition, int index, int parentIndex, int childIndex, FlowPhysicsSettings settings); - void toIsolatedJoint(float length, int childIndex, const QString& group); -}; - - class FlowThread { public: FlowThread() {}; diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index eb02f07e62..7a00a8ecf2 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -1911,14 +1911,12 @@ void Rig::initAnimGraph(const QUrl& url) { qCritical(animation) << "Error loading: code = " << error << "str =" << str; }); - /* connect(this, &Rig::onLoadComplete, [&]() { - if (_internalFlow.getActive()) { - _internalFlow.calculateConstraints(_animSkeleton, _internalPoseSet._relativePoses, _internalPoseSet._absolutePoses); - _networkFlow.calculateConstraints(_animSkeleton, _internalPoseSet._relativePoses, _internalPoseSet._absolutePoses); - } + _internalFlow.setActive(false); + _internalFlow.cleanUp(); + _networkFlow.setActive(false); + _networkFlow.cleanUp(); }); - */ } } @@ -2136,5 +2134,6 @@ void Rig::initFlow(bool isActive) { } } else { _internalFlow.cleanUp(); + _networkFlow.cleanUp(); } } \ No newline at end of file From afed0b54421a662da8910d3e930be5218532a86b Mon Sep 17 00:00:00 2001 From: amantley Date: Thu, 21 Feb 2019 11:08:29 -0800 Subject: [PATCH 103/112] review changes --- interface/src/avatar/MyAvatar.cpp | 4 ++-- interface/src/avatar/MySkeletonModel.cpp | 2 ++ interface/src/avatar/MySkeletonModel.h | 1 - libraries/animation/src/AnimPoleVectorConstraint.h | 4 ---- libraries/avatars-renderer/src/avatars-renderer/Avatar.h | 1 - 5 files changed, 4 insertions(+), 8 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 8ae59ebdc1..5bccd4650b 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -2952,9 +2952,9 @@ void MyAvatar::initAnimGraph() { } else { graphUrl = PathUtils::resourcesUrl("avatar/avatar-animation.json"); - #if defined(Q_OS_ANDROID) || defined(HIFI_USE_Q_OS_ANDROID) +#if defined(Q_OS_ANDROID) || defined(HIFI_USE_Q_OS_ANDROID) graphUrl = PathUtils::resourcesUrl("avatar/avatar-animation_withSplineIKNode.json"); - #endif +#endif } emit animGraphUrlChanged(graphUrl); diff --git a/interface/src/avatar/MySkeletonModel.cpp b/interface/src/avatar/MySkeletonModel.cpp index 86a0dceae0..58071cfab1 100755 --- a/interface/src/avatar/MySkeletonModel.cpp +++ b/interface/src/avatar/MySkeletonModel.cpp @@ -10,12 +10,14 @@ #include #include +#include #include "Application.h" #include "InterfaceLogging.h" #include "AnimUtil.h" + MySkeletonModel::MySkeletonModel(Avatar* owningAvatar, QObject* parent) : SkeletonModel(owningAvatar, parent) { } diff --git a/interface/src/avatar/MySkeletonModel.h b/interface/src/avatar/MySkeletonModel.h index 7ea142b011..9a3559ddf7 100644 --- a/interface/src/avatar/MySkeletonModel.h +++ b/interface/src/avatar/MySkeletonModel.h @@ -12,7 +12,6 @@ #include #include #include "MyAvatar.h" -#include /// A skeleton loaded from a model. class MySkeletonModel : public SkeletonModel { diff --git a/libraries/animation/src/AnimPoleVectorConstraint.h b/libraries/animation/src/AnimPoleVectorConstraint.h index d0c80a393b..44e22671c1 100644 --- a/libraries/animation/src/AnimPoleVectorConstraint.h +++ b/libraries/animation/src/AnimPoleVectorConstraint.h @@ -25,8 +25,6 @@ public: const QString& enabledVar, const QString& poleVectorVar); virtual ~AnimPoleVectorConstraint() override; - float findThetaNewWay(const glm::vec3& hand, const glm::vec3& shoulder, bool left) const; - virtual const AnimPoseVec& evaluate(const AnimVariantMap& animVars, const AnimContext& context, float dt, AnimVariantMap& triggersOut) override; protected: @@ -66,8 +64,6 @@ protected: float _interpAlphaVel { 0.0f }; float _interpAlpha { 0.0f }; - float _lastTheta { 0.0f }; - AnimChain _snapshotChain; // no copies diff --git a/libraries/avatars-renderer/src/avatars-renderer/Avatar.h b/libraries/avatars-renderer/src/avatars-renderer/Avatar.h index 11bf2986d1..c9f1c4bdfe 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/Avatar.h +++ b/libraries/avatars-renderer/src/avatars-renderer/Avatar.h @@ -25,7 +25,6 @@ #include #include #include -#include #include #include From 64ec28ef449c79cc9de41fb4476a711ed61a8859 Mon Sep 17 00:00:00 2001 From: amantley Date: Thu, 21 Feb 2019 11:37:14 -0800 Subject: [PATCH 104/112] added back missing unity meta files --- .../avatars-renderer/src/avatars-renderer/Avatar.cpp | 1 + libraries/shared/src/AvatarConstants.h | 2 +- tools/unity-avatar-exporter/Assets/Editor.meta | 8 ++++++++ tools/unity-avatar-exporter/Assets/README.txt.meta | 7 +++++++ 4 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 tools/unity-avatar-exporter/Assets/Editor.meta create mode 100644 tools/unity-avatar-exporter/Assets/README.txt.meta diff --git a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp index ff99f0dc29..2a3b7e8b46 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp +++ b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp @@ -37,6 +37,7 @@ #include "RenderableModelEntityItem.h" #include +#include #include "Logging.h" diff --git a/libraries/shared/src/AvatarConstants.h b/libraries/shared/src/AvatarConstants.h index 10bfcc77d3..94c2500a04 100644 --- a/libraries/shared/src/AvatarConstants.h +++ b/libraries/shared/src/AvatarConstants.h @@ -20,7 +20,7 @@ const float DEFAULT_AVATAR_EYE_TO_TOP_OF_HEAD = 0.11f; // meters const float DEFAULT_AVATAR_NECK_TO_TOP_OF_HEAD = 0.185f; // meters const float DEFAULT_AVATAR_NECK_HEIGHT = DEFAULT_AVATAR_HEIGHT - DEFAULT_AVATAR_NECK_TO_TOP_OF_HEAD; const float DEFAULT_AVATAR_EYE_HEIGHT = DEFAULT_AVATAR_HEIGHT - DEFAULT_AVATAR_EYE_TO_TOP_OF_HEAD; -const float DEFAULT_SPINE2_SPLINE_PROPORTION = 0.75f; +const float DEFAULT_SPINE2_SPLINE_PROPORTION = 0.71f; const float DEFAULT_AVATAR_SUPPORT_BASE_LEFT = -0.25f; const float DEFAULT_AVATAR_SUPPORT_BASE_RIGHT = 0.25f; const float DEFAULT_AVATAR_SUPPORT_BASE_FRONT = -0.20f; diff --git a/tools/unity-avatar-exporter/Assets/Editor.meta b/tools/unity-avatar-exporter/Assets/Editor.meta new file mode 100644 index 0000000000..cf7dcf12dd --- /dev/null +++ b/tools/unity-avatar-exporter/Assets/Editor.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 02111c50e71dd664da8ad5c6a6eca767 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/tools/unity-avatar-exporter/Assets/README.txt.meta b/tools/unity-avatar-exporter/Assets/README.txt.meta new file mode 100644 index 0000000000..148fd21fdd --- /dev/null +++ b/tools/unity-avatar-exporter/Assets/README.txt.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 30b2b6221fd08234eb07c4d6d525d32e +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: From de10aebbb51b438cf5c85a1f85bf96e27ba04a56 Mon Sep 17 00:00:00 2001 From: amantley Date: Thu, 21 Feb 2019 11:44:18 -0800 Subject: [PATCH 105/112] removed white space --- libraries/shared/src/AvatarConstants.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/shared/src/AvatarConstants.h b/libraries/shared/src/AvatarConstants.h index 94c2500a04..d55a63b960 100644 --- a/libraries/shared/src/AvatarConstants.h +++ b/libraries/shared/src/AvatarConstants.h @@ -20,7 +20,7 @@ const float DEFAULT_AVATAR_EYE_TO_TOP_OF_HEAD = 0.11f; // meters const float DEFAULT_AVATAR_NECK_TO_TOP_OF_HEAD = 0.185f; // meters const float DEFAULT_AVATAR_NECK_HEIGHT = DEFAULT_AVATAR_HEIGHT - DEFAULT_AVATAR_NECK_TO_TOP_OF_HEAD; const float DEFAULT_AVATAR_EYE_HEIGHT = DEFAULT_AVATAR_HEIGHT - DEFAULT_AVATAR_EYE_TO_TOP_OF_HEAD; -const float DEFAULT_SPINE2_SPLINE_PROPORTION = 0.71f; +const float DEFAULT_SPINE2_SPLINE_PROPORTION = 0.71f; const float DEFAULT_AVATAR_SUPPORT_BASE_LEFT = -0.25f; const float DEFAULT_AVATAR_SUPPORT_BASE_RIGHT = 0.25f; const float DEFAULT_AVATAR_SUPPORT_BASE_FRONT = -0.20f; From 0bdc527ce71defad80f1d0405bbe40fab1bf52d7 Mon Sep 17 00:00:00 2001 From: amantley Date: Thu, 21 Feb 2019 13:14:51 -0800 Subject: [PATCH 106/112] turned off pole vector when hand behind back --- libraries/animation/src/Rig.cpp | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index f2b4be077f..93c9c0cd1b 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -1874,11 +1874,13 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s unitAxis = Vectors::UNIT_Y; } + if ((armToHand.z < 0.0f) && (armToHand.y < 0.0f)) { + // turn off the poleVector when the hand is back and down + return false; + } + // get the pole vector theta based on the hand position relative to the shoulder. float positionalTheta = getHandPositionTheta(armToHand, defaultArmLength, left); - if (left) { - qCDebug(animation) << "positional theta left "<< positionalTheta; - } // now we calculate the contribution of the hand rotation relative to the arm glm::quat relativeHandRotation = (elbowPose.inverse() * handPose).rot(); @@ -1966,14 +1968,20 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s // limit the correction anatomically possible angles and change to radians const float LOWER_ANATOMICAL_ANGLE = 175.0f; const float UPPER_ANATOMICAL_ANGLE = 50.0f; + + // make the lower boundary vary with the body + float lowerBoundary = LOWER_ANATOMICAL_ANGLE; + if (fabsf(positionalTheta) < LOWER_ANATOMICAL_ANGLE) { + lowerBoundary = positionalTheta; + } float thetaRadians = 0.0f; if (left) { - if (_lastThetaLeft > -50.0f) { - _lastThetaLeft = -50.0f; + if (_lastThetaLeft > -UPPER_ANATOMICAL_ANGLE) { + _lastThetaLeft = -UPPER_ANATOMICAL_ANGLE; } - if (_lastThetaLeft < -LOWER_ANATOMICAL_ANGLE) { - _lastThetaLeft = -LOWER_ANATOMICAL_ANGLE; + if (_lastThetaLeft < lowerBoundary) { + _lastThetaLeft = lowerBoundary; } // convert to radians and make 180 0 to match pole vector theta thetaRadians = ((180.0f - _lastThetaLeft) / 180.0f)*PI; @@ -1982,8 +1990,8 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s if (_lastThetaRight < UPPER_ANATOMICAL_ANGLE) { _lastThetaRight = UPPER_ANATOMICAL_ANGLE; } - if (_lastThetaRight > LOWER_ANATOMICAL_ANGLE) { - _lastThetaRight = LOWER_ANATOMICAL_ANGLE; + if (_lastThetaRight > lowerBoundary) { + _lastThetaRight = lowerBoundary; } // convert to radians and make 180 0 to match pole vector theta thetaRadians = ((180.0f - _lastThetaRight) / 180.0f)*PI; From 50bc8d3646a3a73cc1e9139cb66c43e664f59d9e Mon Sep 17 00:00:00 2001 From: amantley Date: Thu, 21 Feb 2019 13:32:28 -0800 Subject: [PATCH 107/112] added protected function to cubic hermite spline --- libraries/shared/src/CubicHermiteSpline.h | 42 ++++++++++------------- 1 file changed, 18 insertions(+), 24 deletions(-) diff --git a/libraries/shared/src/CubicHermiteSpline.h b/libraries/shared/src/CubicHermiteSpline.h index 4742bb2e09..c83000996b 100644 --- a/libraries/shared/src/CubicHermiteSpline.h +++ b/libraries/shared/src/CubicHermiteSpline.h @@ -66,19 +66,8 @@ public: memset(_values, 0, sizeof(float) * (NUM_SUBDIVISIONS + 1)); } CubicHermiteSplineFunctorWithArcLength(const glm::vec3& p0, const glm::vec3& m0, const glm::vec3& p1, const glm::vec3& m1) : CubicHermiteSplineFunctor(p0, m0, p1, m1) { - // initialize _values with the accumulated arcLength along the spline. - const float DELTA = 1.0f / NUM_SUBDIVISIONS; - float alpha = 0.0f; - float accum = 0.0f; - _values[0] = 0.0f; - glm::vec3 prevValue = this->operator()(alpha); - for (int i = 1; i < NUM_SUBDIVISIONS + 1; i++) { - glm::vec3 nextValue = this->operator()(alpha + DELTA); - accum += glm::distance(prevValue, nextValue); - alpha += DELTA; - _values[i] = accum; - prevValue = nextValue; - } + + initValues(); } CubicHermiteSplineFunctorWithArcLength(const glm::quat& tipRot, const glm::vec3& tipTrans, const glm::quat& baseRot, const glm::vec3& baseTrans, float baseGain = 1.0f, float tipGain = 1.0f) : CubicHermiteSplineFunctor() { @@ -89,17 +78,7 @@ public: _p1 = tipTrans; _m1 = tipGain * linearDistance * (tipRot * Vectors::UNIT_Y); - // initialize _values with the accumulated arcLength along the spline. - const float DELTA = 1.0f / NUM_SUBDIVISIONS; - float alpha = 0.0f; - float accum = 0.0f; - _values[0] = 0.0f; - for (int i = 1; i < NUM_SUBDIVISIONS + 1; i++) { - accum += glm::distance(this->operator()(alpha), - this->operator()(alpha + DELTA)); - alpha += DELTA; - _values[i] = accum; - } + initValues(); } CubicHermiteSplineFunctorWithArcLength(const CubicHermiteSplineFunctorWithArcLength& orig) : CubicHermiteSplineFunctor(orig) { @@ -131,6 +110,21 @@ public: } protected: float _values[NUM_SUBDIVISIONS + 1]; + + void initValues() { + // initialize _values with the accumulated arcLength along the spline. + const float DELTA = 1.0f / NUM_SUBDIVISIONS; + float alpha = 0.0f; + float accum = 0.0f; + _values[0] = 0.0f; + for (int i = 1; i < NUM_SUBDIVISIONS + 1; i++) { + accum += glm::distance(this->operator()(alpha), + this->operator()(alpha + DELTA)); + alpha += DELTA; + _values[i] = accum; + } + + } }; #endif // hifi_CubicHermiteSpline_h From 6323f49f26217f39aeda8dde12c68213e7add993 Mon Sep 17 00:00:00 2001 From: amantley Date: Thu, 21 Feb 2019 14:36:05 -0800 Subject: [PATCH 108/112] changed the define variable to HIFI_USE_OPTIMIZED_IK --- CMakeLists.txt | 12 +- interface/src/avatar/MyAvatar.cpp | 2 +- interface/src/avatar/MySkeletonModel.cpp | 4 +- libraries/animation/src/Rig.cpp | 334 ----------------------- libraries/animation/src/Rig.h | 14 - 5 files changed, 8 insertions(+), 358 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5bd4d4620b..f88f8fbff7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -52,7 +52,7 @@ else() set(MOBILE 0) endif() -set(HIFI_USE_Q_OS_ANDROID_OPTION OFF) +set(HIFI_USE_OPTIMIZED_IK OFF) set(BUILD_CLIENT_OPTION ON) set(BUILD_SERVER_OPTION ON) set(BUILD_TESTS_OPTION OFF) @@ -109,7 +109,7 @@ if (USE_GLES AND (NOT ANDROID)) set(DISABLE_QML_OPTION ON) endif() -option(HIFI_USE_Q_OS_ANDROID "USE OPTIMIZED IK" ${HIFI_USE_Q_OS_ANDROID_OPTION}) +option(HIFI_USE_OPTIMIZED_IK "USE OPTIMIZED IK" ${HIFI_USE_OPTIMIZED_IK_OPTION}) option(BUILD_CLIENT "Build client components" ${BUILD_CLIENT_OPTION}) option(BUILD_SERVER "Build server components" ${BUILD_SERVER_OPTION}) option(BUILD_TESTS "Build tests" ${BUILD_TESTS_OPTION}) @@ -140,7 +140,7 @@ foreach(PLATFORM_QT_COMPONENT ${PLATFORM_QT_COMPONENTS}) list(APPEND PLATFORM_QT_LIBRARIES "Qt5::${PLATFORM_QT_COMPONENT}") endforeach() -MESSAGE(STATUS "USE OPTIMIZED IK: " ${HIFI_USE_Q_OS_ANDROID}) +MESSAGE(STATUS "USE OPTIMIZED IK: " ${HIFI_USE_OPTIMIZED_IK}) MESSAGE(STATUS "Build server: " ${BUILD_SERVER}) MESSAGE(STATUS "Build client: " ${BUILD_CLIENT}) MESSAGE(STATUS "Build tests: " ${BUILD_TESTS}) @@ -186,11 +186,9 @@ find_package( Threads ) add_definitions(-DGLM_FORCE_RADIANS) add_definitions(-DGLM_ENABLE_EXPERIMENTAL) add_definitions(-DGLM_FORCE_CTOR_INIT) -#add_definitions(-DHIFI_USE_Q_OS_ANDROID) -#option(HIFI_USE_Q_OS_ANDROID_OPTION "hifi_use_optimized_ik" OFF) -if (HIFI_USE_Q_OS_ANDROID) +if (HIFI_USE_OPTIMIZED_IK) MESSAGE(STATUS "SET THE USE IK DEFINITION ") - add_definitions(-DHIFI_USE_Q_OS_ANDROID) + add_definitions(-DHIFI_USE_OPTIMIZED_IK) endif() set(HIFI_LIBRARY_DIR "${CMAKE_CURRENT_SOURCE_DIR}/libraries") diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 5bccd4650b..ff865172ae 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -2952,7 +2952,7 @@ void MyAvatar::initAnimGraph() { } else { graphUrl = PathUtils::resourcesUrl("avatar/avatar-animation.json"); -#if defined(Q_OS_ANDROID) || defined(HIFI_USE_Q_OS_ANDROID) +#if defined(Q_OS_ANDROID) || defined(HIFI_USE_OPTIMIZED_IK) graphUrl = PathUtils::resourcesUrl("avatar/avatar-animation_withSplineIKNode.json"); #endif } diff --git a/interface/src/avatar/MySkeletonModel.cpp b/interface/src/avatar/MySkeletonModel.cpp index 58071cfab1..13cdedc830 100755 --- a/interface/src/avatar/MySkeletonModel.cpp +++ b/interface/src/avatar/MySkeletonModel.cpp @@ -252,7 +252,7 @@ void MySkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) { AnimPose headAvatarSpace(avatarHeadPose.getRotation(), avatarHeadPose.getTranslation()); AnimPose headRigSpace = avatarToRigPose * headAvatarSpace; AnimPose hipsRigSpace = sensorToRigPose * sensorHips; -#if defined(Q_OS_ANDROID) || defined(HIFI_USE_Q_OS_ANDROID) +#if defined(Q_OS_ANDROID) || defined(HIFI_USE_OPTIMIZED_IK) glm::vec3 spine2TargetTranslation = computeSpine2WithHeadHipsSpline(myAvatar, hipsRigSpace, headRigSpace); #endif const float SPINE2_ROTATION_FILTER = 0.5f; @@ -276,7 +276,7 @@ void MySkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) { } generateBasisVectors(up, fwd, u, v, w); AnimPose newSpinePose(glm::mat4(glm::vec4(w, 0.0f), glm::vec4(u, 0.0f), glm::vec4(v, 0.0f), glm::vec4(glm::vec3(0.0f, 0.0f, 0.0f), 1.0f))); -#if defined(Q_OS_ANDROID) || defined(HIFI_USE_Q_OS_ANDROID) +#if defined(Q_OS_ANDROID) || defined(HIFI_USE_OPTIMIZED_IK) currentSpine2Pose.trans() = spine2TargetTranslation; #endif currentSpine2Pose.rot() = safeLerp(currentSpine2Pose.rot(), newSpinePose.rot(), SPINE2_ROTATION_FILTER); diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index 93c9c0cd1b..be6240017f 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -1459,12 +1459,7 @@ void Rig::updateHands(bool leftHandEnabled, bool rightHandEnabled, bool hipsEnab int oppositeArmJointIndex = _animSkeleton->nameToJointIndex("RightArm"); if (ENABLE_POLE_VECTORS && handJointIndex >= 0 && armJointIndex >= 0 && elbowJointIndex >= 0 && oppositeArmJointIndex >= 0) { glm::vec3 poleVector; -#if defined(Q_OS_ANDROID) || defined(HIFI_USE_Q_OS_ANDROID) - bool isLeft = true; - bool usePoleVector = calculateElbowPoleVectorOptimized(handJointIndex, elbowJointIndex, armJointIndex, isLeft, poleVector); -#else bool usePoleVector = calculateElbowPoleVector(handJointIndex, elbowJointIndex, armJointIndex, oppositeArmJointIndex, poleVector); -#endif if (usePoleVector) { glm::vec3 sensorPoleVector = transformVectorFast(rigToSensorMatrix, poleVector); _animVars.set("leftHandPoleVectorEnabled", true); @@ -1519,12 +1514,7 @@ void Rig::updateHands(bool leftHandEnabled, bool rightHandEnabled, bool hipsEnab if (ENABLE_POLE_VECTORS && handJointIndex >= 0 && armJointIndex >= 0 && elbowJointIndex >= 0 && oppositeArmJointIndex >= 0) { glm::vec3 poleVector; -#if defined(Q_OS_ANDROID) || defined(HIFI_USE_Q_OS_ANDROID) - bool isLeft = false; - bool usePoleVector = calculateElbowPoleVectorOptimized(handJointIndex, elbowJointIndex, armJointIndex, isLeft, poleVector); -#else bool usePoleVector = calculateElbowPoleVector(handJointIndex, elbowJointIndex, armJointIndex, oppositeArmJointIndex, poleVector); -#endif if (usePoleVector) { glm::vec3 sensorPoleVector = transformVectorFast(rigToSensorMatrix, poleVector); _animVars.set("rightHandPoleVectorEnabled", true); @@ -1690,330 +1680,6 @@ void Rig::updateEyeJoint(int index, const glm::vec3& modelTranslation, const glm } } -static float getHandPositionTheta(glm::vec3 armToHand, float defaultArmLength, bool left) { - float handPositionTheta = 0.0f; - //calculate the hand position influence on theta - const float zStart = 0.6f; - const float xStart = 0.1f; - // biases - const glm::vec3 biases(0.0f, 135.0f, 0.0f); - // weights - const float zWeightBottom = -100.0f; - const glm::vec3 weights(-50.0f, 60.0f, 90.0f); - - float yFactor = (fabsf(armToHand[1] / defaultArmLength) * weights[1]) + biases[1]; - - float zFactor; - if (armToHand[1] > 0.0f) { - zFactor = weights[2] * glm::max(zStart - (armToHand[2] / defaultArmLength), 0.0f) * glm::max(fabsf((armToHand[1] - 0.1f) / defaultArmLength), 0.0f); - } else { - zFactor = zWeightBottom * glm::max(zStart - (armToHand[2] / defaultArmLength), 0.0f) * fabsf(armToHand[1] / defaultArmLength); - } - - float xFactor; - if (left) { - xFactor = weights[0] * ((-1.0f * (armToHand[0] / defaultArmLength) + xStart) - (0.2f) * ((1.0f + (armToHand[1] / defaultArmLength)) / 2.0f)); - } else { - xFactor = weights[0] * (((armToHand[0] / defaultArmLength) + xStart) - (0.2f) * ((1.0f + (armToHand[1] / defaultArmLength)) / 2.0f)); - } - - handPositionTheta = xFactor + yFactor + zFactor; - - const float LOWER_ANATOMICAL_ANGLE = 175.0f; - const float UPPER_ANATOMICAL_ANGLE = 50.0f; - if (handPositionTheta > LOWER_ANATOMICAL_ANGLE) { - handPositionTheta = LOWER_ANATOMICAL_ANGLE; - } - if (handPositionTheta < UPPER_ANATOMICAL_ANGLE) { - handPositionTheta = UPPER_ANATOMICAL_ANGLE; - } - - if (left) { - handPositionTheta *= -1.0f; - } - - return handPositionTheta; -} - -static float computeUlnarRadialCompensation(float ulnarRadialTheta, float twistTheta, bool left) { - const float ULNAR_BOUNDARY_MINUS = -PI / 4.0f; - const float ULNAR_BOUNDARY_PLUS = -PI / 4.0f; - float ulnarDiff = 0.0f; - float ulnarCorrection = 0.0f; - float currentWristCoefficient = 0.0f; - if (left) { - if (ulnarRadialTheta > -ULNAR_BOUNDARY_MINUS) { - ulnarDiff = ulnarRadialTheta - (-ULNAR_BOUNDARY_MINUS); - } else if (ulnarRadialTheta < -ULNAR_BOUNDARY_PLUS) { - ulnarDiff = ulnarRadialTheta - (-ULNAR_BOUNDARY_PLUS); - } - } else { - if (ulnarRadialTheta > ULNAR_BOUNDARY_MINUS) { - ulnarDiff = ulnarRadialTheta - ULNAR_BOUNDARY_MINUS; - } else if (ulnarRadialTheta < ULNAR_BOUNDARY_PLUS) { - ulnarDiff = ulnarRadialTheta - ULNAR_BOUNDARY_PLUS; - } - - } - if (fabsf(ulnarDiff) > 0.0f) { - float twistCoefficient = 0.0f; - - if (left) { - twistCoefficient = twistTheta; - if (twistCoefficient > (PI / 6.0f)) { - twistCoefficient = 1.0f; - } else { - twistCoefficient = 0.0f; - } - } else { - twistCoefficient = twistTheta; - if (twistCoefficient < (-PI / 6.0f)) { - twistCoefficient = 1.0f; - } else { - twistCoefficient = 0.0f; - } - - } - - if (twistTheta < 0.0f) { - if (left) { - ulnarCorrection -= glm::sign(ulnarDiff) * (fabsf(ulnarDiff) / PI) * 180.0f * twistCoefficient; - } else { - ulnarCorrection += glm::sign(ulnarDiff) * (fabsf(ulnarDiff) / PI) * 180.0f * twistCoefficient; - } - } else { - if (left) { - ulnarCorrection += glm::sign(ulnarDiff) * (fabsf(ulnarDiff) / PI) * 180.0f * twistCoefficient; - } else { - ulnarCorrection -= glm::sign(ulnarDiff) * (fabsf(ulnarDiff) / PI) * 180.0f * twistCoefficient; - } - } - if (fabsf(ulnarCorrection) > 100.0f) { - ulnarCorrection = glm::sign(ulnarCorrection) * 100.0f; - } - currentWristCoefficient += ulnarCorrection; - } - - return currentWristCoefficient; - - -} - -static float computeTwistCompensation(float twistTheta, bool left) { - - const float TWIST_DEADZONE = PI / 2.0f; - float twistCorrection = 0.0f; - - if (fabsf(twistTheta) > TWIST_DEADZONE) { - twistCorrection = glm::sign(twistTheta) * ((fabsf(twistTheta) - TWIST_DEADZONE) / PI) * 90.0f; - } - // limit the twist correction - if (fabsf(twistCorrection) > 30.0f) { - twistCorrection = glm::sign(twistCorrection) * 30.0f; - } - - return twistCorrection; -} - -static float computeFlexCompensation(float flexTheta, bool left) { - - const float FLEX_BOUNDARY = PI / 6.0f; - const float EXTEND_BOUNDARY = -PI / 4.0f; - float flexCorrection = 0.0f; - float currentWristCoefficient = 0.0f; - - if (flexTheta > FLEX_BOUNDARY) { - flexCorrection = ((flexTheta - FLEX_BOUNDARY) / PI) * 60.0f; - } else if (flexTheta < EXTEND_BOUNDARY) { - flexCorrection = ((flexTheta - EXTEND_BOUNDARY) / PI) * 60.0f; - } - if (fabsf(flexCorrection) > 175.0f) { - flexCorrection = glm::sign(flexCorrection) * 175.0f; - } - if (left) { - currentWristCoefficient += flexCorrection; - } else { - currentWristCoefficient -= flexCorrection; - } - - return currentWristCoefficient; - -} - -static float getAxisThetaFromRotation(glm::vec3 axis, glm::quat rotation) { - - //get the flex/extension of the wrist rotation - glm::quat rotationAboutTheAxis; - glm::quat rotationOrthoganalToAxis; - swingTwistDecomposition(rotation, axis, rotationOrthoganalToAxis, rotationAboutTheAxis); - if (rotationAboutTheAxis.w < 0.0f) { - rotationAboutTheAxis *= -1.0f; - } - glm::vec3 rotAxis = glm::axis(rotationAboutTheAxis); - float axisTheta = glm::sign(glm::dot(rotAxis, axis)) * glm::angle(rotationAboutTheAxis); - - return axisTheta; -} - -bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int shoulderIndex, bool left, glm::vec3& poleVector) { - - AnimPose handPose = _externalPoseSet._absolutePoses[handIndex]; - AnimPose shoulderPose = _externalPoseSet._absolutePoses[shoulderIndex]; - AnimPose elbowPose = _externalPoseSet._absolutePoses[elbowIndex]; - - AnimPose absoluteShoulderPose = getAbsoluteDefaultPose(shoulderIndex); - AnimPose absoluteHandPose = getAbsoluteDefaultPose(handIndex); - float defaultArmLength = glm::length(absoluteHandPose.trans() - absoluteShoulderPose.trans()); - - glm::vec3 armToHand = handPose.trans() - shoulderPose.trans(); - glm::vec3 unitAxis; - float axisLength = glm::length(armToHand); - if (axisLength > 0.0f) { - unitAxis = armToHand / axisLength; - } else { - unitAxis = Vectors::UNIT_Y; - } - - if ((armToHand.z < 0.0f) && (armToHand.y < 0.0f)) { - // turn off the poleVector when the hand is back and down - return false; - } - - // get the pole vector theta based on the hand position relative to the shoulder. - float positionalTheta = getHandPositionTheta(armToHand, defaultArmLength, left); - - // now we calculate the contribution of the hand rotation relative to the arm - glm::quat relativeHandRotation = (elbowPose.inverse() * handPose).rot(); - if (relativeHandRotation.w < 0.0f) { - relativeHandRotation *= -1.0f; - } - - // find the thetas, hand relative to avatar arm - const glm::vec3 ULNAR_ROTATION_AXIS = Vectors::UNIT_Z; - const glm::vec3 TWIST_ROTATION_AXIS = Vectors::UNIT_Y; - const glm::vec3 FLEX__ROTATION_AXIS = Vectors::UNIT_X; - - float ulnarDeviationTheta = getAxisThetaFromRotation(ULNAR_ROTATION_AXIS, relativeHandRotation); - float flexTheta = getAxisThetaFromRotation(FLEX__ROTATION_AXIS, relativeHandRotation); - float trueTwistTheta = getAxisThetaFromRotation(TWIST_ROTATION_AXIS, relativeHandRotation); - - const float HALFWAY_ANGLE = PI / 2.0f; - const float SMOOTHING_COEFFICIENT = 0.5f; - if (left) { - - if (glm::sign(ulnarDeviationTheta) != glm::sign(_ulnarRadialThetaRunningAverageLeft) && fabsf(ulnarDeviationTheta) > HALFWAY_ANGLE) { - // don't allow the theta to cross the 180 degree limit. ie don't go from 179 to -179 degrees - ulnarDeviationTheta = -1.0f * ulnarDeviationTheta; - } - if (glm::sign(flexTheta) != glm::sign(_flexThetaRunningAverageLeft) && fabsf(flexTheta) > HALFWAY_ANGLE) { - // don't allow the theta to cross the 180 degree limit. - flexTheta = -1.0f * flexTheta; - } - if (glm::sign(trueTwistTheta) != glm::sign(_twistThetaRunningAverageLeft) && fabsf(trueTwistTheta) > HALFWAY_ANGLE) { - // don't allow the theta to cross the 180 degree limit. - trueTwistTheta = -1.0f * trueTwistTheta; - } - - // put some smoothing on the thetas - _ulnarRadialThetaRunningAverageLeft = ulnarDeviationTheta; - _flexThetaRunningAverageLeft = SMOOTHING_COEFFICIENT * _flexThetaRunningAverageLeft + (1.0f - SMOOTHING_COEFFICIENT) * flexTheta; - _twistThetaRunningAverageLeft = SMOOTHING_COEFFICIENT * _twistThetaRunningAverageLeft + (1.0f - SMOOTHING_COEFFICIENT) * trueTwistTheta; - - } else { - - if (glm::sign(ulnarDeviationTheta) != glm::sign(_ulnarRadialThetaRunningAverageRight) && fabsf(ulnarDeviationTheta) > HALFWAY_ANGLE) { - // don't allow the theta to cross the 180 degree limit. ie don't go from 179 to -179 degrees - ulnarDeviationTheta = -1.0f * ulnarDeviationTheta; - } - if (glm::sign(flexTheta) != glm::sign(_flexThetaRunningAverageRight) && fabsf(flexTheta) > HALFWAY_ANGLE) { - // don't allow the theta to cross the 180 degree limit. - flexTheta = -1.0f * flexTheta; - } - if (glm::sign(trueTwistTheta) != glm::sign(_twistThetaRunningAverageRight) && fabsf(trueTwistTheta) > HALFWAY_ANGLE) { - // don't allow the theta to cross the 180 degree limit. - trueTwistTheta = -1.0f * trueTwistTheta; - } - - // put some smoothing on the thetas - _twistThetaRunningAverageRight = SMOOTHING_COEFFICIENT * _twistThetaRunningAverageRight + (1.0f - SMOOTHING_COEFFICIENT) * trueTwistTheta; - _flexThetaRunningAverageRight = SMOOTHING_COEFFICIENT * _flexThetaRunningAverageRight + (1.0f - SMOOTHING_COEFFICIENT) * flexTheta; - _ulnarRadialThetaRunningAverageRight = ulnarDeviationTheta; - } - - // get the correction angle for each axis and add it to the base pole vector theta - float currentWristCoefficient = 0.0f; - if (left) { - currentWristCoefficient += computeTwistCompensation(_twistThetaRunningAverageLeft, left); - currentWristCoefficient += computeFlexCompensation(_flexThetaRunningAverageLeft, left); - //currentWristCoefficient += computeUlnarRadialCompensation(_ulnarRadialThetaRunningAverageLeft, _twistThetaRunningAverageLeft, left); - } else { - currentWristCoefficient += computeTwistCompensation(_twistThetaRunningAverageRight, left); - currentWristCoefficient += computeFlexCompensation(_flexThetaRunningAverageRight, left); - //currentWristCoefficient += computeUlnarRadialCompensation(_ulnarRadialThetaRunningAverageRight, _twistThetaRunningAverageRight, left); - } - - // find the previous contribution of the wrist and add the current wrist correction to it - if (left) { - _lastWristCoefficientLeft = _lastThetaLeft - _lastPositionThetaLeft; - _lastWristCoefficientLeft += currentWristCoefficient; - _lastPositionThetaLeft = positionalTheta; - _lastThetaLeft = positionalTheta + _lastWristCoefficientLeft; - } else { - _lastWristCoefficientRight = _lastThetaRight - _lastPositionThetaRight; - _lastWristCoefficientRight += currentWristCoefficient; - _lastPositionThetaRight = positionalTheta; - _lastThetaRight = positionalTheta + _lastWristCoefficientRight; - } - - // limit the correction anatomically possible angles and change to radians - const float LOWER_ANATOMICAL_ANGLE = 175.0f; - const float UPPER_ANATOMICAL_ANGLE = 50.0f; - - // make the lower boundary vary with the body - float lowerBoundary = LOWER_ANATOMICAL_ANGLE; - if (fabsf(positionalTheta) < LOWER_ANATOMICAL_ANGLE) { - lowerBoundary = positionalTheta; - } - float thetaRadians = 0.0f; - if (left) { - - if (_lastThetaLeft > -UPPER_ANATOMICAL_ANGLE) { - _lastThetaLeft = -UPPER_ANATOMICAL_ANGLE; - } - if (_lastThetaLeft < lowerBoundary) { - _lastThetaLeft = lowerBoundary; - } - // convert to radians and make 180 0 to match pole vector theta - thetaRadians = ((180.0f - _lastThetaLeft) / 180.0f)*PI; - } else { - - if (_lastThetaRight < UPPER_ANATOMICAL_ANGLE) { - _lastThetaRight = UPPER_ANATOMICAL_ANGLE; - } - if (_lastThetaRight > lowerBoundary) { - _lastThetaRight = lowerBoundary; - } - // convert to radians and make 180 0 to match pole vector theta - thetaRadians = ((180.0f - _lastThetaRight) / 180.0f)*PI; - } - - // convert the final theta to a pole vector value - float poleVectorXValue = -1.0f * sinf(thetaRadians); - float poleVectorYValue = -1.0f * cosf(thetaRadians); - float poleVectorZValue = 0.0f; - glm::vec3 thetaVector(poleVectorXValue, poleVectorYValue, poleVectorZValue); - - glm::vec3 up = Vectors::UNIT_Y; - glm::vec3 fwd = armToHand/glm::length(armToHand); - glm::vec3 u, v, w; - - generateBasisVectors(fwd, up, u, v, w); - AnimPose armAxisPose(glm::mat4(glm::vec4(-w, 0.0f), glm::vec4(v, 0.0f), glm::vec4(u, 0.0f), glm::vec4(glm::vec3(0.0f, 0.0f, 0.0f), 1.0f))); - poleVector = armAxisPose * thetaVector; - - return true; -} - bool Rig::calculateElbowPoleVector(int handIndex, int elbowIndex, int armIndex, int oppositeArmIndex, glm::vec3& poleVector) const { // The resulting Pole Vector is calculated as the sum of a three vectors. // The first is the vector with direction shoulder-hand. The module of this vector is inversely proportional to the strength of the resulting Pole Vector. diff --git a/libraries/animation/src/Rig.h b/libraries/animation/src/Rig.h index 6f1a5906bb..41c25a3c3e 100644 --- a/libraries/animation/src/Rig.h +++ b/libraries/animation/src/Rig.h @@ -258,7 +258,6 @@ protected: void calcAnimAlpha(float speed, const std::vector& referenceSpeeds, float* alphaOut) const; bool calculateElbowPoleVector(int handIndex, int elbowIndex, int armIndex, int oppositeArmIndex, glm::vec3& poleVector) const; - bool calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int shoulderIndex, bool left, glm::vec3& poleVector); glm::vec3 calculateKneePoleVector(int footJointIndex, int kneeJoint, int upLegIndex, int hipsIndex, const AnimPose& targetFootPose) const; glm::vec3 deflectHandFromTorso(const glm::vec3& handPosition, const HFMJointShapeInfo& hipsShapeInfo, const HFMJointShapeInfo& spineShapeInfo, const HFMJointShapeInfo& spine1ShapeInfo, const HFMJointShapeInfo& spine2ShapeInfo) const; @@ -420,19 +419,6 @@ protected: bool _computeNetworkAnimation { false }; bool _sendNetworkNode { false }; - float _twistThetaRunningAverageLeft { 0.0f }; - float _flexThetaRunningAverageLeft { 0.0f }; - float _ulnarRadialThetaRunningAverageLeft { 0.0f }; - float _twistThetaRunningAverageRight { 0.0f }; - float _flexThetaRunningAverageRight { 0.0f }; - float _ulnarRadialThetaRunningAverageRight { 0.0f }; - float _lastThetaLeft { 0.0f }; - float _lastThetaRight { 0.0f }; - float _lastWristCoefficientRight { 0.0f }; - float _lastWristCoefficientLeft { 0.0f }; - float _lastPositionThetaLeft { 0.0f }; - float _lastPositionThetaRight { 0.0f }; - AnimContext _lastContext; AnimVariantMap _lastAnimVars; From 5cf8a963cdd4481d67254b4adad946c065dbdc51 Mon Sep 17 00:00:00 2001 From: amantley Date: Thu, 21 Feb 2019 15:41:16 -0800 Subject: [PATCH 109/112] make spine2 rotation damping only happen in optimized code. the regular code is already damped --- interface/src/avatar/MySkeletonModel.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/interface/src/avatar/MySkeletonModel.cpp b/interface/src/avatar/MySkeletonModel.cpp index 13cdedc830..aa45a1f0bb 100755 --- a/interface/src/avatar/MySkeletonModel.cpp +++ b/interface/src/avatar/MySkeletonModel.cpp @@ -265,7 +265,9 @@ void MySkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) { if (spine2Exists && headExists && hipsExists) { AnimPose rigSpaceYaw(myAvatar->getSpine2RotationRigSpace()); +#if defined(Q_OS_ANDROID) || defined(HIFI_USE_OPTIMIZED_IK) rigSpaceYaw.rot() = safeLerp(Quaternions::IDENTITY, rigSpaceYaw.rot(), 0.5f); +#endif glm::vec3 u, v, w; glm::vec3 fwd = rigSpaceYaw.rot() * glm::vec3(0.0f, 0.0f, 1.0f); glm::vec3 up = currentHeadPose.trans() - currentHipsPose.trans(); From dcbf57ee0b5df0fcde392bc14534c26db6ee85dc Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Thu, 21 Feb 2019 16:41:24 -0700 Subject: [PATCH 110/112] Fix linux warning and HMD breaks flow --- libraries/animation/src/Flow.cpp | 4 ---- libraries/animation/src/Rig.cpp | 7 ------- libraries/render-utils/src/Model.cpp | 1 + 3 files changed, 1 insertion(+), 11 deletions(-) diff --git a/libraries/animation/src/Flow.cpp b/libraries/animation/src/Flow.cpp index 9fb0306fa3..3bb80b9375 100644 --- a/libraries/animation/src/Flow.cpp +++ b/libraries/animation/src/Flow.cpp @@ -460,16 +460,12 @@ void Flow::calculateConstraints(const std::shared_ptr& skeleton, if (!skeleton) { return; } - int rightHandIndex = -1; auto flowPrefix = FLOW_JOINT_PREFIX.toUpper(); auto simPrefix = SIM_JOINT_PREFIX.toUpper(); std::vector handsIndices; for (int i = 0; i < skeleton->getNumJoints(); i++) { auto name = skeleton->getJointName(i); - if (name == "RightHand") { - rightHandIndex = i; - } if (std::find(HAND_COLLISION_JOINTS.begin(), HAND_COLLISION_JOINTS.end(), name) != HAND_COLLISION_JOINTS.end()) { handsIndices.push_back(i); } diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index 7a00a8ecf2..4d5488cad2 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -1910,13 +1910,6 @@ void Rig::initAnimGraph(const QUrl& url) { connect(_networkLoader.get(), &AnimNodeLoader::error, [networkUrl](int error, QString str) { qCritical(animation) << "Error loading: code = " << error << "str =" << str; }); - - connect(this, &Rig::onLoadComplete, [&]() { - _internalFlow.setActive(false); - _internalFlow.cleanUp(); - _networkFlow.setActive(false); - _networkFlow.cleanUp(); - }); } } diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 260e25009e..f61ae28db4 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -1158,6 +1158,7 @@ void Model::setURL(const QUrl& url) { resource->setLoadPriority(this, _loadingPriority); _renderWatcher.setResource(resource); } + _rig.initFlow(false); onInvalidate(); } From 3bf5c44f9885a218515bccee41dc418cf2d3f990 Mon Sep 17 00:00:00 2001 From: amantley Date: Thu, 21 Feb 2019 16:24:46 -0800 Subject: [PATCH 111/112] fixed build warnings --- interface/src/avatar/MySkeletonModel.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/interface/src/avatar/MySkeletonModel.cpp b/interface/src/avatar/MySkeletonModel.cpp index aa45a1f0bb..55c29b66c1 100755 --- a/interface/src/avatar/MySkeletonModel.cpp +++ b/interface/src/avatar/MySkeletonModel.cpp @@ -35,6 +35,7 @@ Rig::CharacterControllerState convertCharacterControllerState(CharacterControlle }; } +#if defined(Q_OS_ANDROID) || defined(HIFI_USE_OPTIMIZED_IK) static glm::vec3 computeSpine2WithHeadHipsSpline(MyAvatar* myAvatar, AnimPose hipsIKTargetPose, AnimPose headIKTargetPose) { // the the ik targets to compute the spline with @@ -48,6 +49,7 @@ static glm::vec3 computeSpine2WithHeadHipsSpline(MyAvatar* myAvatar, AnimPose hi return spine2Translation + myAvatar->getSpine2SplineOffset(); } +#endif static AnimPose computeHipsInSensorFrame(MyAvatar* myAvatar, bool isFlying) { glm::mat4 worldToSensorMat = glm::inverse(myAvatar->getSensorToWorldMatrix()); @@ -249,10 +251,10 @@ void MySkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) { myAvatar->getControllerPoseInAvatarFrame(controller::Action::LEFT_HAND).isValid() && !(params.primaryControllerFlags[Rig::PrimaryControllerType_Spine2] & (uint8_t)Rig::ControllerFlags::Enabled)) { +#if defined(Q_OS_ANDROID) || defined(HIFI_USE_OPTIMIZED_IK) AnimPose headAvatarSpace(avatarHeadPose.getRotation(), avatarHeadPose.getTranslation()); AnimPose headRigSpace = avatarToRigPose * headAvatarSpace; AnimPose hipsRigSpace = sensorToRigPose * sensorHips; -#if defined(Q_OS_ANDROID) || defined(HIFI_USE_OPTIMIZED_IK) glm::vec3 spine2TargetTranslation = computeSpine2WithHeadHipsSpline(myAvatar, hipsRigSpace, headRigSpace); #endif const float SPINE2_ROTATION_FILTER = 0.5f; From 3072ca43de06bc413c61673ace32ad1ba20ba966 Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Fri, 22 Feb 2019 09:24:38 -0700 Subject: [PATCH 112/112] Detailed picking if avatar is not null --- interface/src/avatar/AvatarManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index 22f8e7112a..55025b3b23 100755 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -719,7 +719,7 @@ RayToAvatarIntersectionResult AvatarManager::findRayIntersectionVector(const Pic } } - if (rayAvatarResult._intersect && pickAgainstMesh) { + if (avatar && rayAvatarResult._intersect && pickAgainstMesh) { glm::vec3 localRayOrigin = avatar->worldToJointPoint(ray.origin, rayAvatarResult._intersectWithJoint); glm::vec3 localRayPoint = avatar->worldToJointPoint(ray.origin + rayAvatarResult._distance * rayDirection, rayAvatarResult._intersectWithJoint);