From 4fd80ff6bc7bb2f31671164aaa86b701f39023db Mon Sep 17 00:00:00 2001 From: amantley Date: Tue, 8 Jan 2019 15:26:46 -0800 Subject: [PATCH 001/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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/137] 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 2202b695751a70837e321240581eeab51a955ec1 Mon Sep 17 00:00:00 2001 From: David Kelly Date: Wed, 20 Feb 2019 10:18:55 -0700 Subject: [PATCH 095/137] Guard against accidentally calling wrong api/v1/places endpoint spaces --- domain-server/src/DomainServer.cpp | 2 +- libraries/networking/src/AddressManager.cpp | 6 ++++-- scripts/system/interstitialPage.js | 5 +++++ 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 258038b8f1..85b116129c 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -2548,7 +2548,7 @@ bool DomainServer::processPendingContent(HTTPConnection* connection, QString ite _pendingFileContent.seek(_pendingFileContent.size()); _pendingFileContent.write(dataChunk); _pendingFileContent.close(); - + // Respond immediately - will timeout if we wait for restore. connection->respond(HTTPConnection::StatusCode200); if (itemName == "restore-file" || itemName == "restore-file-chunk-final" || itemName == "restore-file-chunk-only") { diff --git a/libraries/networking/src/AddressManager.cpp b/libraries/networking/src/AddressManager.cpp index 9145b4a79e..f4221e3d49 100644 --- a/libraries/networking/src/AddressManager.cpp +++ b/libraries/networking/src/AddressManager.cpp @@ -315,7 +315,9 @@ bool AddressManager::handleUrl(const QUrl& lookupUrl, LookupTrigger trigger) { // wasn't an address - lookup the place name // we may have a path that defines a relative viewpoint - pass that through the lookup so we can go to it after - attemptPlaceNameLookup(lookupUrl.host(), lookupUrl.path(), trigger); + if (!lookupUrl.host().isNull() && !lookupUrl.host().isEmpty()) { + attemptPlaceNameLookup(lookupUrl.host(), lookupUrl.path(), trigger); + } } } @@ -337,7 +339,7 @@ bool AddressManager::handleUrl(const QUrl& lookupUrl, LookupTrigger trigger) { // be loaded over http(s) // lookupUrl.scheme() == URL_SCHEME_HTTP || // lookupUrl.scheme() == HIFI_URL_SCHEME_HTTPS || - // TODO once a file can return a connection refusal if there were to be some kind of load error, we'd + // TODO once a file can return a connection refusal if there were to be some kind of load error, we'd // need to store the previous domain tried in _lastVisitedURL. For now , do not store it. _previousAPILookup.clear(); diff --git a/scripts/system/interstitialPage.js b/scripts/system/interstitialPage.js index 8dd94623b7..8ecc982dab 100644 --- a/scripts/system/interstitialPage.js +++ b/scripts/system/interstitialPage.js @@ -325,6 +325,11 @@ leftMargin: domainNameLeftMargin }; + // check to be sure we are going to look for an actual domain + if (!domain) { + doRequest = false; + } + if (doRequest) { var url = Account.metaverseServerURL + '/api/v1/places/' + domain; request({ From 95b3fbdc35de9d9569052aa97840965005d9fb52 Mon Sep 17 00:00:00 2001 From: amantley Date: Wed, 20 Feb 2019 15:02:12 -0800 Subject: [PATCH 096/137] 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 097/137] 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 098/137] 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 099/137] 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 100/137] 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 101/137] 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 102/137] 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 103/137] 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 104/137] 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 105/137] 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 106/137] 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 107/137] 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 108/137] 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 544f54e69a7b55e2b01b0008a26f257dd7c04f4b Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Thu, 21 Feb 2019 14:10:36 -0800 Subject: [PATCH 109/137] fix model scale --- interface/src/ui/overlays/Overlays.cpp | 15 +++++++-- .../entities/src/EntityItemProperties.cpp | 10 ++++++ libraries/entities/src/EntityItemProperties.h | 1 + libraries/entities/src/EntityPropertyFlags.h | 31 ++++++++++--------- libraries/entities/src/ModelEntityItem.cpp | 17 ++++++++++ libraries/entities/src/ModelEntityItem.h | 4 +++ libraries/networking/src/udt/PacketHeaders.h | 1 + libraries/shared/src/SpatiallyNestable.cpp | 2 +- 8 files changed, 62 insertions(+), 19 deletions(-) diff --git a/interface/src/ui/overlays/Overlays.cpp b/interface/src/ui/overlays/Overlays.cpp index 660220c731..081085408d 100644 --- a/interface/src/ui/overlays/Overlays.cpp +++ b/interface/src/ui/overlays/Overlays.cpp @@ -311,7 +311,11 @@ EntityItemProperties Overlays::convertOverlayToEntityProperties(QVariantMap& ove RENAME_PROP(start, position); } RENAME_PROP(point, position); - RENAME_PROP(scale, dimensions); + if (type != "Model") { + RENAME_PROP(scale, dimensions); + } else { + RENAME_PROP(scale, modelScale); + } RENAME_PROP(size, dimensions); RENAME_PROP(orientation, rotation); RENAME_PROP(localOrientation, localRotation); @@ -636,7 +640,11 @@ QVariantMap Overlays::convertEntityToOverlayProperties(const EntityItemPropertie RENAME_PROP(position, start); } RENAME_PROP(position, point); - RENAME_PROP(dimensions, scale); + if (type != "Model") { + RENAME_PROP(dimensions, scale); + } else { + RENAME_PROP(modelScale, scale); + } RENAME_PROP(dimensions, size); RENAME_PROP(ignorePickIntersection, ignoreRayIntersection); @@ -1718,7 +1726,8 @@ QVector Overlays::findOverlays(const glm::vec3& center, float radius) { * * @property {Vec3} position - The position of the overlay center. Synonyms: p1, point, and * start. - * @property {Vec3} dimensions - The dimensions of the overlay. Synonyms: scale, size. + * @property {Vec3} dimensions - The dimensions of the overlay. Synonyms: size. + * @property {Vec3} scale - The scale factor applied to the model's dimensions. * @property {Quat} rotation - The orientation of the overlay. Synonym: orientation. * @property {Vec3} localPosition - The local position of the overlay relative to its parent if the overlay has a * parentID set, otherwise the same value as position. diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index 6738b1cedd..75e2069471 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -580,6 +580,7 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { // Model CHECK_PROPERTY_CHANGE(PROP_MODEL_URL, modelURL); + CHECK_PROPERTY_CHANGE(PROP_MODEL_SCALE, modelScale); CHECK_PROPERTY_CHANGE(PROP_JOINT_ROTATIONS_SET, jointRotationsSet); CHECK_PROPERTY_CHANGE(PROP_JOINT_ROTATIONS, jointRotations); CHECK_PROPERTY_CHANGE(PROP_JOINT_TRANSLATIONS_SET, jointTranslationsSet); @@ -1012,6 +1013,7 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { * @property {Vec3} dimensions=0.1,0.1,0.1 - The dimensions of the entity. When adding an entity, if no dimensions * value is specified then the model is automatically sized to its * {@link Entities.EntityProperties|naturalDimensions}. + * @property {Vec3} modelScale - The scale factor applied to the model's dimensions. * @property {Color} color=255,255,255 - Currently not used. * @property {string} modelURL="" - The URL of the FBX of OBJ model. Baked FBX models' URLs end in ".baked.fbx".
* @property {string} textures="" - A JSON string of texture name, URL pairs used when rendering the model in place of the @@ -1683,6 +1685,7 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_TEXTURES, textures); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_MODEL_URL, modelURL); + COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_MODEL_SCALE, modelScale); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_JOINT_ROTATIONS_SET, jointRotationsSet); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_JOINT_ROTATIONS, jointRotations); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_JOINT_TRANSLATIONS_SET, jointTranslationsSet); @@ -2078,6 +2081,7 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object, bool // Model COPY_PROPERTY_FROM_QSCRIPTVALUE(modelURL, QString, setModelURL); + COPY_PROPERTY_FROM_QSCRIPTVALUE(modelScale, vec3, setModelScale); COPY_PROPERTY_FROM_QSCRIPTVALUE(jointRotationsSet, qVectorBool, setJointRotationsSet); COPY_PROPERTY_FROM_QSCRIPTVALUE(jointRotations, qVectorQuat, setJointRotations); COPY_PROPERTY_FROM_QSCRIPTVALUE(jointTranslationsSet, qVectorBool, setJointTranslationsSet); @@ -2357,6 +2361,7 @@ void EntityItemProperties::merge(const EntityItemProperties& other) { // Model COPY_PROPERTY_IF_CHANGED(modelURL); + COPY_PROPERTY_IF_CHANGED(modelScale); COPY_PROPERTY_IF_CHANGED(jointRotationsSet); COPY_PROPERTY_IF_CHANGED(jointRotations); COPY_PROPERTY_IF_CHANGED(jointTranslationsSet); @@ -2700,6 +2705,7 @@ bool EntityItemProperties::getPropertyInfo(const QString& propertyName, EntityPr // Model ADD_PROPERTY_TO_MAP(PROP_MODEL_URL, ModelURL, modelURL, QString); + ADD_PROPERTY_TO_MAP(PROP_MODEL_SCALE, ModelScale, modelScale, vec3); ADD_PROPERTY_TO_MAP(PROP_JOINT_ROTATIONS_SET, JointRotationsSet, jointRotationsSet, QVector); ADD_PROPERTY_TO_MAP(PROP_JOINT_ROTATIONS, JointRotations, jointRotations, QVector); ADD_PROPERTY_TO_MAP(PROP_JOINT_TRANSLATIONS_SET, JointTranslationsSet, jointTranslationsSet, QVector); @@ -3989,6 +3995,7 @@ void EntityItemProperties::markAllChanged() { // Model _modelURLChanged = true; + _modelScaleChanged = true; _jointRotationsSetChanged = true; _jointRotationsChanged = true; _jointTranslationsSetChanged = true; @@ -4526,6 +4533,9 @@ QList EntityItemProperties::listChangedProperties() { if (modelURLChanged()) { out += "modelURL"; } + if (modelScaleChanged()) { + out += "scale"; + } if (jointRotationsSetChanged()) { out += "jointRotationsSet"; } diff --git a/libraries/entities/src/EntityItemProperties.h b/libraries/entities/src/EntityItemProperties.h index 712f2d120f..afc3537559 100644 --- a/libraries/entities/src/EntityItemProperties.h +++ b/libraries/entities/src/EntityItemProperties.h @@ -279,6 +279,7 @@ public: // Model DEFINE_PROPERTY_REF(PROP_MODEL_URL, ModelURL, modelURL, QString, ""); + DEFINE_PROPERTY_REF(PROP_MODEL_SCALE, ModelScale, modelScale, glm::vec3, glm::vec3(1.0f)); DEFINE_PROPERTY_REF(PROP_JOINT_ROTATIONS_SET, JointRotationsSet, jointRotationsSet, QVector, QVector()); DEFINE_PROPERTY_REF(PROP_JOINT_ROTATIONS, JointRotations, jointRotations, QVector, QVector()); DEFINE_PROPERTY_REF(PROP_JOINT_TRANSLATIONS_SET, JointTranslationsSet, jointTranslationsSet, QVector, QVector()); diff --git a/libraries/entities/src/EntityPropertyFlags.h b/libraries/entities/src/EntityPropertyFlags.h index 093df92dc1..cce30c9614 100644 --- a/libraries/entities/src/EntityPropertyFlags.h +++ b/libraries/entities/src/EntityPropertyFlags.h @@ -202,22 +202,23 @@ enum EntityPropertyList { // Model PROP_MODEL_URL = PROP_DERIVED_0, - PROP_JOINT_ROTATIONS_SET = PROP_DERIVED_1, - PROP_JOINT_ROTATIONS = PROP_DERIVED_2, - PROP_JOINT_TRANSLATIONS_SET = PROP_DERIVED_3, - PROP_JOINT_TRANSLATIONS = PROP_DERIVED_4, - PROP_RELAY_PARENT_JOINTS = PROP_DERIVED_5, - PROP_GROUP_CULLED = PROP_DERIVED_6, + PROP_MODEL_SCALE = PROP_DERIVED_1, + PROP_JOINT_ROTATIONS_SET = PROP_DERIVED_2, + PROP_JOINT_ROTATIONS = PROP_DERIVED_3, + PROP_JOINT_TRANSLATIONS_SET = PROP_DERIVED_4, + PROP_JOINT_TRANSLATIONS = PROP_DERIVED_5, + PROP_RELAY_PARENT_JOINTS = PROP_DERIVED_6, + PROP_GROUP_CULLED = PROP_DERIVED_7, // Animation - PROP_ANIMATION_URL = PROP_DERIVED_7, - PROP_ANIMATION_ALLOW_TRANSLATION = PROP_DERIVED_8, - PROP_ANIMATION_FPS = PROP_DERIVED_9, - PROP_ANIMATION_FRAME_INDEX = PROP_DERIVED_10, - PROP_ANIMATION_PLAYING = PROP_DERIVED_11, - PROP_ANIMATION_LOOP = PROP_DERIVED_12, - PROP_ANIMATION_FIRST_FRAME = PROP_DERIVED_13, - PROP_ANIMATION_LAST_FRAME = PROP_DERIVED_14, - PROP_ANIMATION_HOLD = PROP_DERIVED_15, + PROP_ANIMATION_URL = PROP_DERIVED_8, + PROP_ANIMATION_ALLOW_TRANSLATION = PROP_DERIVED_9, + PROP_ANIMATION_FPS = PROP_DERIVED_10, + PROP_ANIMATION_FRAME_INDEX = PROP_DERIVED_11, + PROP_ANIMATION_PLAYING = PROP_DERIVED_12, + PROP_ANIMATION_LOOP = PROP_DERIVED_13, + PROP_ANIMATION_FIRST_FRAME = PROP_DERIVED_14, + PROP_ANIMATION_LAST_FRAME = PROP_DERIVED_15, + PROP_ANIMATION_HOLD = PROP_DERIVED_16, // Light PROP_IS_SPOTLIGHT = PROP_DERIVED_0, diff --git a/libraries/entities/src/ModelEntityItem.cpp b/libraries/entities/src/ModelEntityItem.cpp index e365d0a7b6..bb8f375302 100644 --- a/libraries/entities/src/ModelEntityItem.cpp +++ b/libraries/entities/src/ModelEntityItem.cpp @@ -63,6 +63,7 @@ EntityItemProperties ModelEntityItem::getProperties(const EntityPropertyFlags& d COPY_ENTITY_PROPERTY_TO_PROPERTIES(textures, getTextures); COPY_ENTITY_PROPERTY_TO_PROPERTIES(modelURL, getModelURL); + COPY_ENTITY_PROPERTY_TO_PROPERTIES(modelScale, getModelScale); COPY_ENTITY_PROPERTY_TO_PROPERTIES(jointRotationsSet, getJointRotationsSet); COPY_ENTITY_PROPERTY_TO_PROPERTIES(jointRotations, getJointRotations); COPY_ENTITY_PROPERTY_TO_PROPERTIES(jointTranslationsSet, getJointTranslationsSet); @@ -85,6 +86,7 @@ bool ModelEntityItem::setProperties(const EntityItemProperties& properties) { SET_ENTITY_PROPERTY_FROM_PROPERTIES(textures, setTextures); SET_ENTITY_PROPERTY_FROM_PROPERTIES(modelURL, setModelURL); + SET_ENTITY_PROPERTY_FROM_PROPERTIES(modelScale, setModelScale); SET_ENTITY_PROPERTY_FROM_PROPERTIES(jointRotationsSet, setJointRotationsSet); SET_ENTITY_PROPERTY_FROM_PROPERTIES(jointRotations, setJointRotations); SET_ENTITY_PROPERTY_FROM_PROPERTIES(jointTranslationsSet, setJointTranslationsSet); @@ -128,6 +130,7 @@ int ModelEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data, READ_ENTITY_PROPERTY(PROP_TEXTURES, QString, setTextures); READ_ENTITY_PROPERTY(PROP_MODEL_URL, QString, setModelURL); + READ_ENTITY_PROPERTY(PROP_MODEL_SCALE, glm::vec3, setModelScale); READ_ENTITY_PROPERTY(PROP_JOINT_ROTATIONS_SET, QVector, setJointRotationsSet); READ_ENTITY_PROPERTY(PROP_JOINT_ROTATIONS, QVector, setJointRotations); READ_ENTITY_PROPERTY(PROP_JOINT_TRANSLATIONS_SET, QVector, setJointTranslationsSet); @@ -165,6 +168,7 @@ EntityPropertyFlags ModelEntityItem::getEntityProperties(EncodeBitstreamParams& requestedProperties += PROP_TEXTURES; requestedProperties += PROP_MODEL_URL; + requestedProperties += PROP_MODEL_SCALE; requestedProperties += PROP_JOINT_ROTATIONS_SET; requestedProperties += PROP_JOINT_ROTATIONS; requestedProperties += PROP_JOINT_TRANSLATIONS_SET; @@ -192,6 +196,7 @@ void ModelEntityItem::appendSubclassData(OctreePacketData* packetData, EncodeBit APPEND_ENTITY_PROPERTY(PROP_TEXTURES, getTextures()); APPEND_ENTITY_PROPERTY(PROP_MODEL_URL, getModelURL()); + APPEND_ENTITY_PROPERTY(PROP_MODEL_SCALE, getModelScale()); APPEND_ENTITY_PROPERTY(PROP_JOINT_ROTATIONS_SET, getJointRotationsSet()); APPEND_ENTITY_PROPERTY(PROP_JOINT_ROTATIONS, getJointRotations()); APPEND_ENTITY_PROPERTY(PROP_JOINT_TRANSLATIONS_SET, getJointTranslationsSet()); @@ -708,3 +713,15 @@ bool ModelEntityItem::applyNewAnimationProperties(AnimationPropertyGroup newProp } return somethingChanged; } + +glm::vec3 ModelEntityItem::getModelScale() const { + return _modelScaleLock.resultWithReadLock([&] { + return getSNScale(); + }); +} + +void ModelEntityItem::setModelScale(const glm::vec3& modelScale) { + _modelScaleLock.withWriteLock([&] { + setSNScale(modelScale); + }); +} \ No newline at end of file diff --git a/libraries/entities/src/ModelEntityItem.h b/libraries/entities/src/ModelEntityItem.h index 649a6cb50f..234cfa435e 100644 --- a/libraries/entities/src/ModelEntityItem.h +++ b/libraries/entities/src/ModelEntityItem.h @@ -126,6 +126,9 @@ public: QVector getJointTranslations() const; QVector getJointTranslationsSet() const; + glm::vec3 getModelScale() const; + void setModelScale(const glm::vec3& modelScale); + private: void setAnimationSettings(const QString& value); // only called for old bitstream format bool applyNewAnimationProperties(AnimationPropertyGroup newProperties); @@ -141,6 +144,7 @@ protected: // they aren't currently updated from data in the model/rig, and they don't have a direct effect // on what's rendered. ReadWriteLockable _jointDataLock; + ReadWriteLockable _modelScaleLock; bool _jointRotationsExplicitlySet { false }; // were the joints set as a property or just side effect of animations bool _jointTranslationsExplicitlySet{ false }; // were the joints set as a property or just side effect of animations diff --git a/libraries/networking/src/udt/PacketHeaders.h b/libraries/networking/src/udt/PacketHeaders.h index 5f55c189ce..b6fcd2f2ce 100644 --- a/libraries/networking/src/udt/PacketHeaders.h +++ b/libraries/networking/src/udt/PacketHeaders.h @@ -262,6 +262,7 @@ enum class EntityVersion : PacketVersion { RingGizmoEntities, ShowKeyboardFocusHighlight, WebBillboardMode, + ModelScale, // Add new versions above here NUM_PACKET_TYPE, diff --git a/libraries/shared/src/SpatiallyNestable.cpp b/libraries/shared/src/SpatiallyNestable.cpp index 19fafdccf4..b48b8d0e16 100644 --- a/libraries/shared/src/SpatiallyNestable.cpp +++ b/libraries/shared/src/SpatiallyNestable.cpp @@ -861,7 +861,7 @@ void SpatiallyNestable::setSNScale(const glm::vec3& scale, bool& success) { } }); if (success && changed) { - locationChanged(); + dimensionsChanged(); } } From 6323f49f26217f39aeda8dde12c68213e7add993 Mon Sep 17 00:00:00 2001 From: amantley Date: Thu, 21 Feb 2019 14:36:05 -0800 Subject: [PATCH 110/137] 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 111/137] 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 112/137] 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 113/137] 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 982c4c2bc40d607bbd152f09454eda5428b63441 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 21 Feb 2019 16:33:31 -0800 Subject: [PATCH 114/137] do not Space::clear() in clearNonLocalEntities() --- libraries/entities-renderer/src/EntityTreeRenderer.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index 9d55d936a2..914c0f97a0 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -219,7 +219,6 @@ void EntityTreeRenderer::clearNonLocalEntities() { std::unordered_map savedEntities; // remove all entities from the scene - _space->clear(); auto scene = _viewState->getMain3DScene(); if (scene) { render::Transaction transaction; @@ -1392,4 +1391,4 @@ bool EntityTreeRenderer::removeMaterialFromAvatar(const QUuid& avatarID, graphic return _removeMaterialFromAvatarOperator(avatarID, material, parentMaterialName); } return false; -} \ No newline at end of file +} From be2d4272da65adc644064abb68a55b7cb395bafd Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 21 Feb 2019 18:11:16 -0800 Subject: [PATCH 115/137] remove the other unnecessary _space->clear() --- libraries/entities-renderer/src/EntityTreeRenderer.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index 914c0f97a0..efd1399f30 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -258,8 +258,6 @@ void EntityTreeRenderer::clear() { resetEntitiesScriptEngine(); } // remove all entities from the scene - - _space->clear(); auto scene = _viewState->getMain3DScene(); if (scene) { render::Transaction transaction; From c1786edc2445797631c2c87a9d448c4ff42f7e35 Mon Sep 17 00:00:00 2001 From: Ken Cooke Date: Thu, 21 Feb 2019 17:47:28 -0800 Subject: [PATCH 116/137] Emulate the old behavior of _lastInputLoudness --- interface/src/scripting/Audio.cpp | 5 +++-- libraries/audio-client/src/AudioClient.cpp | 20 ++++++++++++++------ libraries/audio-client/src/AudioClient.h | 6 ++++-- 3 files changed, 21 insertions(+), 10 deletions(-) diff --git a/interface/src/scripting/Audio.cpp b/interface/src/scripting/Audio.cpp index fb64dbe098..2c4c29ff65 100644 --- a/interface/src/scripting/Audio.cpp +++ b/interface/src/scripting/Audio.cpp @@ -27,8 +27,9 @@ QString Audio::HMD { "VR" }; Setting::Handle enableNoiseReductionSetting { QStringList { Audio::AUDIO, "NoiseReduction" }, true }; float Audio::loudnessToLevel(float loudness) { - float level = 6.02059991f * fastLog2f(loudness); // level in dBFS - level = (level + 48.0f) * (1/39.0f); // map [-48, -9] dBFS to [0, 1] + float level = loudness * (1/32768.0f); // level in [0, 1] + level = 6.02059991f * fastLog2f(level); // convert to dBFS + level = (level + 48.0f) * (1/42.0f); // map [-48, -6] dBFS to [0, 1] return glm::clamp(level, 0.0f, 1.0f); } diff --git a/libraries/audio-client/src/AudioClient.cpp b/libraries/audio-client/src/AudioClient.cpp index 60a95ff58a..8c50a195ee 100644 --- a/libraries/audio-client/src/AudioClient.cpp +++ b/libraries/audio-client/src/AudioClient.cpp @@ -175,7 +175,7 @@ static float computeLoudness(int16_t* samples, int numSamples, int numChannels, const int32_t CLIPPING_THRESHOLD = 32392; // -0.1 dBFS const int32_t CLIPPING_DETECTION = 3; // consecutive samples over threshold - float scale = numSamples ? 1.0f / (numSamples * 32768.0f) : 0.0f; + float scale = numSamples ? 1.0f / numSamples : 0.0f; int32_t loudness = 0; isClipping = false; @@ -249,6 +249,8 @@ AudioClient::AudioClient() : _outputBufferSizeFrames("audioOutputBufferFrames", DEFAULT_BUFFER_FRAMES), _sessionOutputBufferSizeFrames(_outputBufferSizeFrames.get()), _outputStarveDetectionEnabled("audioOutputStarveDetectionEnabled", DEFAULT_STARVE_DETECTION_ENABLED), + _lastRawInputLoudness(0.0f), + _lastSmoothedRawInputLoudness(0.0f), _lastInputLoudness(0.0f), _timeSinceLastClip(-1.0f), _muted(false), @@ -1144,6 +1146,9 @@ void AudioClient::handleAudioInput(QByteArray& audioBuffer) { emit inputReceived(audioBuffer); } + // loudness after mute/gate + _lastInputLoudness = (_muted || !audioGateOpen) ? 0.0f : _lastRawInputLoudness; + // detect gate opening and closing bool openedInLastBlock = !_audioGateOpen && audioGateOpen; // the gate just opened bool closedInLastBlock = _audioGateOpen && !audioGateOpen; // the gate just closed @@ -1222,12 +1227,15 @@ void AudioClient::handleMicAudioInput() { // detect loudness and clipping on the raw input bool isClipping = false; - float inputLoudness = computeLoudness(inputAudioSamples.get(), inputSamplesRequired, _inputFormat.channelCount(), isClipping); + float loudness = computeLoudness(inputAudioSamples.get(), inputSamplesRequired, _inputFormat.channelCount(), isClipping); + _lastRawInputLoudness = loudness; - float tc = (inputLoudness > _lastInputLoudness) ? 0.378f : 0.967f; // 10ms attack, 300ms release @ 100Hz - inputLoudness += tc * (_lastInputLoudness - inputLoudness); - _lastInputLoudness = inputLoudness; + // envelope detection + float tc = (loudness > _lastSmoothedRawInputLoudness) ? 0.378f : 0.967f; // 10ms attack, 300ms release @ 100Hz + loudness += tc * (_lastSmoothedRawInputLoudness - loudness); + _lastSmoothedRawInputLoudness = loudness; + // clipping indicator if (isClipping) { _timeSinceLastClip = 0.0f; } else if (_timeSinceLastClip >= 0.0f) { @@ -1235,7 +1243,7 @@ void AudioClient::handleMicAudioInput() { } isClipping = (_timeSinceLastClip >= 0.0f) && (_timeSinceLastClip < 2.0f); // 2 second hold time - emit inputLoudnessChanged(_lastInputLoudness, isClipping); + emit inputLoudnessChanged(_lastSmoothedRawInputLoudness, isClipping); if (!_muted) { possibleResampling(_inputToNetworkResampler, diff --git a/libraries/audio-client/src/AudioClient.h b/libraries/audio-client/src/AudioClient.h index 94ed2ce132..29036b7c71 100644 --- a/libraries/audio-client/src/AudioClient.h +++ b/libraries/audio-client/src/AudioClient.h @@ -127,7 +127,7 @@ public: const QAudioFormat& getOutputFormat() const { return _outputFormat; } - float getLastInputLoudness() const { return _lastInputLoudness; } // TODO: relative to noise floor? + float getLastInputLoudness() const { return _lastInputLoudness; } float getTimeSinceLastClip() const { return _timeSinceLastClip; } float getAudioAverageInputLoudness() const { return _lastInputLoudness; } @@ -355,7 +355,9 @@ private: StDev _stdev; QElapsedTimer _timeSinceLastReceived; - float _lastInputLoudness; + float _lastRawInputLoudness; // before mute/gate + float _lastSmoothedRawInputLoudness; + float _lastInputLoudness; // after mute/gate float _timeSinceLastClip; int _totalInputAudioSamples; From 3072ca43de06bc413c61673ace32ad1ba20ba966 Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Fri, 22 Feb 2019 09:24:38 -0700 Subject: [PATCH 117/137] 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); From 6d6cd42adbdf78fc07f2317b90f7b4941c1a5c38 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Fri, 22 Feb 2019 12:00:00 -0800 Subject: [PATCH 118/137] fix bound scaling --- libraries/entities/src/EntityItem.cpp | 10 +++++----- libraries/entities/src/EntityItemProperties.cpp | 2 +- libraries/render-utils/src/CauterizedModel.cpp | 1 + libraries/render-utils/src/Model.cpp | 1 + 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index 9f11b3c018..72246f8229 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -266,7 +266,7 @@ OctreeElement::AppendState EntityItem::appendEntityData(OctreePacketData* packet APPEND_ENTITY_PROPERTY(PROP_HREF, getHref()); APPEND_ENTITY_PROPERTY(PROP_DESCRIPTION, getDescription()); APPEND_ENTITY_PROPERTY(PROP_POSITION, getLocalPosition()); - APPEND_ENTITY_PROPERTY(PROP_DIMENSIONS, getUnscaledDimensions()); + APPEND_ENTITY_PROPERTY(PROP_DIMENSIONS, getScaledDimensions()); APPEND_ENTITY_PROPERTY(PROP_ROTATION, getLocalOrientation()); APPEND_ENTITY_PROPERTY(PROP_REGISTRATION_POINT, getRegistrationPoint()); APPEND_ENTITY_PROPERTY(PROP_CREATED, getCreated()); @@ -818,7 +818,7 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef }; READ_ENTITY_PROPERTY(PROP_POSITION, glm::vec3, customUpdatePositionFromNetwork); } - READ_ENTITY_PROPERTY(PROP_DIMENSIONS, glm::vec3, setUnscaledDimensions); + READ_ENTITY_PROPERTY(PROP_DIMENSIONS, glm::vec3, setScaledDimensions); { // See comment above auto customUpdateRotationFromNetwork = [this, shouldUpdate, lastEdited](glm::quat value) { if (shouldUpdate(_lastUpdatedRotationTimestamp, value != _lastUpdatedRotationValue)) { @@ -1315,7 +1315,7 @@ EntityItemProperties EntityItem::getProperties(const EntityPropertyFlags& desire COPY_ENTITY_PROPERTY_TO_PROPERTIES(href, getHref); COPY_ENTITY_PROPERTY_TO_PROPERTIES(description, getDescription); COPY_ENTITY_PROPERTY_TO_PROPERTIES(position, getLocalPosition); - COPY_ENTITY_PROPERTY_TO_PROPERTIES(dimensions, getUnscaledDimensions); + COPY_ENTITY_PROPERTY_TO_PROPERTIES(dimensions, getScaledDimensions); COPY_ENTITY_PROPERTY_TO_PROPERTIES(rotation, getLocalOrientation); COPY_ENTITY_PROPERTY_TO_PROPERTIES(registrationPoint, getRegistrationPoint); COPY_ENTITY_PROPERTY_TO_PROPERTIES(created, getCreated); @@ -1462,7 +1462,7 @@ bool EntityItem::setProperties(const EntityItemProperties& properties) { SET_ENTITY_PROPERTY_FROM_PROPERTIES(href, setHref); SET_ENTITY_PROPERTY_FROM_PROPERTIES(description, setDescription); SET_ENTITY_PROPERTY_FROM_PROPERTIES(position, setPosition); - SET_ENTITY_PROPERTY_FROM_PROPERTIES(dimensions, setUnscaledDimensions); + SET_ENTITY_PROPERTY_FROM_PROPERTIES(dimensions, setScaledDimensions); SET_ENTITY_PROPERTY_FROM_PROPERTIES(rotation, setRotation); SET_ENTITY_PROPERTY_FROM_PROPERTIES(registrationPoint, setRegistrationPoint); SET_ENTITY_PROPERTY_FROM_PROPERTIES(created, setCreated); @@ -1872,7 +1872,7 @@ glm::vec3 EntityItem::getScaledDimensions() const { void EntityItem::setScaledDimensions(const glm::vec3& value) { glm::vec3 parentScale = getSNScale(); - setUnscaledDimensions(value * parentScale); + setUnscaledDimensions(value / parentScale); } void EntityItem::setUnscaledDimensions(const glm::vec3& value) { diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index 75e2069471..7575763bf9 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -1013,7 +1013,7 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { * @property {Vec3} dimensions=0.1,0.1,0.1 - The dimensions of the entity. When adding an entity, if no dimensions * value is specified then the model is automatically sized to its * {@link Entities.EntityProperties|naturalDimensions}. - * @property {Vec3} modelScale - The scale factor applied to the model's dimensions. + * @property {Vec3} modelScale - The scale factor applied to the model's dimensions. Deprecated. * @property {Color} color=255,255,255 - Currently not used. * @property {string} modelURL="" - The URL of the FBX of OBJ model. Baked FBX models' URLs end in ".baked.fbx".
* @property {string} textures="" - A JSON string of texture name, URL pairs used when rendering the model in place of the diff --git a/libraries/render-utils/src/CauterizedModel.cpp b/libraries/render-utils/src/CauterizedModel.cpp index 81a81c5602..cfb78d6bbc 100644 --- a/libraries/render-utils/src/CauterizedModel.cpp +++ b/libraries/render-utils/src/CauterizedModel.cpp @@ -178,6 +178,7 @@ void CauterizedModel::updateClusterMatrices() { } } } + computeMeshPartLocalBounds(); // post the blender if we're not currently waiting for one to finish auto modelBlender = DependencyManager::get(); diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index b9b294d0e3..02c6562f61 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -1385,6 +1385,7 @@ void Model::updateClusterMatrices() { } } } + computeMeshPartLocalBounds(); // post the blender if we're not currently waiting for one to finish auto modelBlender = DependencyManager::get(); From a31b09b204ac32d1cccc3906fdca7e9e9224db55 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Fri, 22 Feb 2019 13:17:13 -0800 Subject: [PATCH 119/137] handle models with no materials --- libraries/graphics/src/graphics/Material.h | 4 ++++ libraries/render-utils/src/RenderPipelines.cpp | 8 ++------ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/libraries/graphics/src/graphics/Material.h b/libraries/graphics/src/graphics/Material.h index fdddf3640a..2fce8e1195 100755 --- a/libraries/graphics/src/graphics/Material.h +++ b/libraries/graphics/src/graphics/Material.h @@ -462,6 +462,9 @@ public: void setTexturesLoading(bool value) { _texturesLoading = value; } bool areTexturesLoading() const { return _texturesLoading; } + bool isInitialized() const { return _initialized; } + void setInitialized() { _initialized = true; } + int getTextureCount() const { calculateMaterialInfo(); return _textureCount; } size_t getTextureSize() const { calculateMaterialInfo(); return _textureSize; } bool hasTextureInfo() const { return _hasCalculatedTextureInfo; } @@ -471,6 +474,7 @@ private: gpu::TextureTablePointer _textureTable { std::make_shared() }; bool _needsUpdate { false }; bool _texturesLoading { false }; + bool _initialized { false }; mutable size_t _textureSize { 0 }; mutable int _textureCount { 0 }; diff --git a/libraries/render-utils/src/RenderPipelines.cpp b/libraries/render-utils/src/RenderPipelines.cpp index 6f6f2ab856..67c3b526b9 100644 --- a/libraries/render-utils/src/RenderPipelines.cpp +++ b/libraries/render-utils/src/RenderPipelines.cpp @@ -382,11 +382,6 @@ void RenderPipelines::bindMaterial(graphics::MaterialPointer& material, gpu::Bat void RenderPipelines::updateMultiMaterial(graphics::MultiMaterial& multiMaterial) { auto& schemaBuffer = multiMaterial.getSchemaBuffer(); - if (multiMaterial.size() == 0) { - schemaBuffer.edit() = graphics::MultiMaterial::Schema(); - return; - } - auto& drawMaterialTextures = multiMaterial.getTextureTable(); multiMaterial.setTexturesLoading(false); @@ -732,6 +727,7 @@ void RenderPipelines::updateMultiMaterial(graphics::MultiMaterial& multiMaterial schema._key = (uint32_t)schemaKey._flags.to_ulong(); schemaBuffer.edit() = schema; multiMaterial.setNeedsUpdate(false); + multiMaterial.setInitialized(); } void RenderPipelines::bindMaterials(graphics::MultiMaterial& multiMaterial, gpu::Batch& batch, bool enableTextures) { @@ -739,7 +735,7 @@ void RenderPipelines::bindMaterials(graphics::MultiMaterial& multiMaterial, gpu: return; } - if (multiMaterial.needsUpdate() || multiMaterial.areTexturesLoading()) { + if (!multiMaterial.isInitialized() || multiMaterial.needsUpdate() || multiMaterial.areTexturesLoading()) { updateMultiMaterial(multiMaterial); } From dbc3ae3793480bf0021341b33863914fffc98f03 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Fri, 22 Feb 2019 14:18:59 -0800 Subject: [PATCH 120/137] hmmm not working --- .../entities-renderer/src/RenderableShapeEntityItem.cpp | 4 ++-- libraries/graphics/src/graphics/Material.h | 7 ++----- libraries/render-utils/src/MeshPartPayload.cpp | 6 +++--- libraries/render-utils/src/RenderPipelines.cpp | 2 +- 4 files changed, 8 insertions(+), 11 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp b/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp index d42a766faa..5f3f4c9e81 100644 --- a/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp @@ -53,7 +53,7 @@ bool ShapeEntityRenderer::needsRenderUpdate() const { } auto mat = _materials.find("0"); - if (mat != _materials.end() && (mat->second.needsUpdate() || mat->second.areTexturesLoading())) { + if (mat != _materials.end() && mat->second.shouldUpdate()) { return true; } @@ -188,7 +188,7 @@ bool ShapeEntityRenderer::useMaterialPipeline(const graphics::MultiMaterial& mat ShapeKey ShapeEntityRenderer::getShapeKey() { auto mat = _materials.find("0"); - if (mat != _materials.end() && (mat->second.needsUpdate() || mat->second.areTexturesLoading())) { + if (mat != _materials.end() && mat->second.shouldUpdate()) { RenderPipelines::updateMultiMaterial(mat->second); } diff --git a/libraries/graphics/src/graphics/Material.h b/libraries/graphics/src/graphics/Material.h index 2fce8e1195..d24e906f98 100755 --- a/libraries/graphics/src/graphics/Material.h +++ b/libraries/graphics/src/graphics/Material.h @@ -456,15 +456,12 @@ public: graphics::MaterialKey getMaterialKey() const { return graphics::MaterialKey(_schemaBuffer.get()._key); } const gpu::TextureTablePointer& getTextureTable() const { return _textureTable; } - bool needsUpdate() const { return _needsUpdate; } void setNeedsUpdate(bool needsUpdate) { _needsUpdate = needsUpdate; } - void setTexturesLoading(bool value) { _texturesLoading = value; } - bool areTexturesLoading() const { return _texturesLoading; } - - bool isInitialized() const { return _initialized; } void setInitialized() { _initialized = true; } + bool shouldUpdate() const { return !_initialized || _needsUpdate || _texturesLoading; } + int getTextureCount() const { calculateMaterialInfo(); return _textureCount; } size_t getTextureSize() const { calculateMaterialInfo(); return _textureSize; } bool hasTextureInfo() const { return _hasCalculatedTextureInfo; } diff --git a/libraries/render-utils/src/MeshPartPayload.cpp b/libraries/render-utils/src/MeshPartPayload.cpp index 6409cdd231..b1104b8aad 100644 --- a/libraries/render-utils/src/MeshPartPayload.cpp +++ b/libraries/render-utils/src/MeshPartPayload.cpp @@ -83,7 +83,7 @@ void MeshPartPayload::updateKey(const render::ItemKey& key) { ItemKey::Builder builder(key); builder.withTypeShape(); - if (_drawMaterials.needsUpdate() || _drawMaterials.areTexturesLoading()) { + if (_drawMaterials.shouldUpdate()) { RenderPipelines::updateMultiMaterial(_drawMaterials); } @@ -329,7 +329,7 @@ void ModelMeshPartPayload::updateKey(const render::ItemKey& key) { builder.withDeformed(); } - if (_drawMaterials.needsUpdate() || _drawMaterials.areTexturesLoading()) { + if (_drawMaterials.shouldUpdate()) { RenderPipelines::updateMultiMaterial(_drawMaterials); } @@ -347,7 +347,7 @@ void ModelMeshPartPayload::setShapeKey(bool invalidateShapeKey, PrimitiveMode pr return; } - if (_drawMaterials.needsUpdate() || _drawMaterials.areTexturesLoading()) { + if (_drawMaterials.shouldUpdate()) { RenderPipelines::updateMultiMaterial(_drawMaterials); } diff --git a/libraries/render-utils/src/RenderPipelines.cpp b/libraries/render-utils/src/RenderPipelines.cpp index 67c3b526b9..83216ddf84 100644 --- a/libraries/render-utils/src/RenderPipelines.cpp +++ b/libraries/render-utils/src/RenderPipelines.cpp @@ -735,7 +735,7 @@ void RenderPipelines::bindMaterials(graphics::MultiMaterial& multiMaterial, gpu: return; } - if (!multiMaterial.isInitialized() || multiMaterial.needsUpdate() || multiMaterial.areTexturesLoading()) { + if (multiMaterial.shouldUpdate()) { updateMultiMaterial(multiMaterial); } From 081e62a64758ff2187edad65c73ff32d9d695676 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Fri, 22 Feb 2019 14:26:15 -0800 Subject: [PATCH 121/137] fix parent loop crash --- libraries/shared/src/SpatiallyNestable.cpp | 9 +++++++-- libraries/shared/src/SpatiallyNestable.h | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/libraries/shared/src/SpatiallyNestable.cpp b/libraries/shared/src/SpatiallyNestable.cpp index 19fafdccf4..8d2e5ea45b 100644 --- a/libraries/shared/src/SpatiallyNestable.cpp +++ b/libraries/shared/src/SpatiallyNestable.cpp @@ -1420,11 +1420,16 @@ QUuid SpatiallyNestable::getEditSenderID() { return editSenderID; } -void SpatiallyNestable::bumpAncestorChainRenderableVersion() const { +void SpatiallyNestable::bumpAncestorChainRenderableVersion(int depth) const { + if (depth > MAX_PARENTING_CHAIN_SIZE) { + breakParentingLoop(); + return; + } + _ancestorChainRenderableVersion++; bool success = false; auto parent = getParentPointer(success); if (success && parent) { - parent->bumpAncestorChainRenderableVersion(); + parent->bumpAncestorChainRenderableVersion(depth + 1); } } \ No newline at end of file diff --git a/libraries/shared/src/SpatiallyNestable.h b/libraries/shared/src/SpatiallyNestable.h index 495c941c07..a802a25e89 100644 --- a/libraries/shared/src/SpatiallyNestable.h +++ b/libraries/shared/src/SpatiallyNestable.h @@ -221,7 +221,7 @@ public: bool hasGrabs(); virtual QUuid getEditSenderID(); - void bumpAncestorChainRenderableVersion() const; + void bumpAncestorChainRenderableVersion(int depth = 0) const; protected: QUuid _id; From 30b6b7f21ba7062b274e32a0b2528ac8b36600ea Mon Sep 17 00:00:00 2001 From: Sam Gondelman Date: Fri, 22 Feb 2019 16:30:36 -0800 Subject: [PATCH 122/137] let's try that again --- libraries/shared/src/SpatiallyNestable.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/shared/src/SpatiallyNestable.cpp b/libraries/shared/src/SpatiallyNestable.cpp index 8d2e5ea45b..6d8140a95d 100644 --- a/libraries/shared/src/SpatiallyNestable.cpp +++ b/libraries/shared/src/SpatiallyNestable.cpp @@ -1422,7 +1422,7 @@ QUuid SpatiallyNestable::getEditSenderID() { void SpatiallyNestable::bumpAncestorChainRenderableVersion(int depth) const { if (depth > MAX_PARENTING_CHAIN_SIZE) { - breakParentingLoop(); + // can't break the parent chain here, because it will call setParentID, which calls this return; } @@ -1432,4 +1432,4 @@ void SpatiallyNestable::bumpAncestorChainRenderableVersion(int depth) const { if (success && parent) { parent->bumpAncestorChainRenderableVersion(depth + 1); } -} \ No newline at end of file +} From 37720e9daafc252d75379f0f8d68588f71973ba2 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Fri, 22 Feb 2019 16:53:03 -0800 Subject: [PATCH 123/137] fix nametag rotation --- interface/src/ui/overlays/Overlays.cpp | 36 ++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/interface/src/ui/overlays/Overlays.cpp b/interface/src/ui/overlays/Overlays.cpp index 660220c731..62a6b88fc0 100644 --- a/interface/src/ui/overlays/Overlays.cpp +++ b/interface/src/ui/overlays/Overlays.cpp @@ -559,6 +559,42 @@ EntityItemProperties Overlays::convertOverlayToEntityProperties(QVariantMap& ove SET_OVERLAY_PROP_DEFAULT(textures, PathUtils::resourcesUrl() + "images/whitePixel.png"); } + { // Overlays did this conversion for rotation + auto iter = overlayProps.find("rotation"); + if (iter != overlayProps.end() && !overlayProps.contains("localRotation")) { + QUuid parentID; + { + auto iter = overlayProps.find("parentID"); + if (iter != overlayProps.end()) { + parentID = iter.value().toUuid(); + } else if (!add) { + EntityPropertyFlags desiredProperties; + desiredProperties += PROP_PARENT_ID; + parentID = DependencyManager::get()->getEntityProperties(id, desiredProperties).getParentID(); + } + } + + int parentJointIndex = -1; + { + auto iter = overlayProps.find("parentJointIndex"); + if (iter != overlayProps.end()) { + parentJointIndex = iter.value().toInt(); + } else if (!add) { + EntityPropertyFlags desiredProperties; + desiredProperties += PROP_PARENT_JOINT_INDEX; + parentJointIndex = DependencyManager::get()->getEntityProperties(id, desiredProperties).getParentJointIndex(); + } + } + + glm::quat rotation = quatFromVariant(iter.value()); + bool success = false; + glm::quat localRotation = SpatiallyNestable::worldToLocal(rotation, parentID, parentJointIndex, false, success); + if (success) { + overlayProps["rotation"] = quatToVariant(localRotation); + } + } + } + if (type == "Text" || type == "Image" || type == "Grid" || type == "Web") { glm::quat originalRotation = ENTITY_ITEM_DEFAULT_ROTATION; { From d040803391511f864ee5f116e1e082f92682f168 Mon Sep 17 00:00:00 2001 From: Clement Date: Fri, 22 Feb 2019 18:07:26 -0800 Subject: [PATCH 124/137] Delete old nodes with identical socket --- libraries/networking/src/LimitedNodeList.cpp | 176 +++++++++---------- 1 file changed, 84 insertions(+), 92 deletions(-) diff --git a/libraries/networking/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp index 8b9e37569c..eaa02f059e 100644 --- a/libraries/networking/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -645,103 +645,95 @@ SharedNodePointer LimitedNodeList::addOrUpdateNode(const QUuid& uuid, NodeType_t const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket, Node::LocalID localID, bool isReplicated, bool isUpstream, const QUuid& connectionSecret, const NodePermissions& permissions) { - QReadLocker readLocker(&_nodeMutex); - NodeHash::const_iterator it = _nodeHash.find(uuid); + { + QReadLocker readLocker(&_nodeMutex); + NodeHash::const_iterator it = _nodeHash.find(uuid); - if (it != _nodeHash.end()) { - SharedNodePointer& matchingNode = it->second; + if (it != _nodeHash.end()) { + SharedNodePointer& matchingNode = it->second; - matchingNode->setPublicSocket(publicSocket); - matchingNode->setLocalSocket(localSocket); - matchingNode->setPermissions(permissions); - matchingNode->setConnectionSecret(connectionSecret); - matchingNode->setIsReplicated(isReplicated); - matchingNode->setIsUpstream(isUpstream || NodeType::isUpstream(nodeType)); - matchingNode->setLocalID(localID); + matchingNode->setPublicSocket(publicSocket); + matchingNode->setLocalSocket(localSocket); + matchingNode->setPermissions(permissions); + matchingNode->setConnectionSecret(connectionSecret); + matchingNode->setIsReplicated(isReplicated); + matchingNode->setIsUpstream(isUpstream || NodeType::isUpstream(nodeType)); + matchingNode->setLocalID(localID); - return matchingNode; - } else { - auto it = _connectionIDs.find(uuid); - if (it == _connectionIDs.end()) { - _connectionIDs[uuid] = INITIAL_CONNECTION_ID; + return matchingNode; } - - // we didn't have this node, so add them - Node* newNode = new Node(uuid, nodeType, publicSocket, localSocket); - newNode->setIsReplicated(isReplicated); - newNode->setIsUpstream(isUpstream || NodeType::isUpstream(nodeType)); - newNode->setConnectionSecret(connectionSecret); - newNode->setPermissions(permissions); - newNode->setLocalID(localID); - - // move the newly constructed node to the LNL thread - newNode->moveToThread(thread()); - - if (nodeType == NodeType::AudioMixer) { - LimitedNodeList::flagTimeForConnectionStep(LimitedNodeList::AddedAudioMixer); - } - - SharedNodePointer newNodePointer(newNode, &QObject::deleteLater); - - // if this is a solo node type, we assume that the DS has replaced its assignment and we should kill the previous node - if (SOLO_NODE_TYPES.count(newNode->getType())) { - // while we still have the read lock, see if there is a previous solo node we'll need to remove - auto previousSoloIt = std::find_if(_nodeHash.cbegin(), _nodeHash.cend(), [newNode](const UUIDNodePair& nodePair){ - return nodePair.second->getType() == newNode->getType(); - }); - - if (previousSoloIt != _nodeHash.cend()) { - // we have a previous solo node, switch to a write lock so we can remove it - readLocker.unlock(); - - QWriteLocker writeLocker(&_nodeMutex); - - auto oldSoloNode = previousSoloIt->second; - - _localIDMap.unsafe_erase(oldSoloNode->getLocalID()); - _nodeHash.unsafe_erase(previousSoloIt); - handleNodeKill(oldSoloNode); - - // convert the current lock back to a read lock for insertion of new node - writeLocker.unlock(); - readLocker.relock(); - } - } - - // insert the new node and release our read lock -#if defined(Q_OS_ANDROID) || (defined(__clang__) && defined(Q_OS_LINUX)) - _nodeHash.insert(UUIDNodePair(newNode->getUUID(), newNodePointer)); - _localIDMap.insert(std::pair(localID, newNodePointer)); -#else - _nodeHash.emplace(newNode->getUUID(), newNodePointer); - _localIDMap.emplace(localID, newNodePointer); -#endif - readLocker.unlock(); - - qCDebug(networking) << "Added" << *newNode; - - auto weakPtr = newNodePointer.toWeakRef(); // We don't want the lambdas to hold a strong ref - - emit nodeAdded(newNodePointer); - if (newNodePointer->getActiveSocket()) { - emit nodeActivated(newNodePointer); - } else { - connect(newNodePointer.data(), &NetworkPeer::socketActivated, this, [this, weakPtr] { - auto sharedPtr = weakPtr.lock(); - if (sharedPtr) { - emit nodeActivated(sharedPtr); - disconnect(sharedPtr.data(), &NetworkPeer::socketActivated, this, 0); - } - }); - } - - // Signal when a socket changes, so we can start the hole punch over. - connect(newNodePointer.data(), &NetworkPeer::socketUpdated, this, [this, weakPtr] { - emit nodeSocketUpdated(weakPtr); - }); - - return newNodePointer; } + + auto removeOldNode = [&](auto node) { + if (node) { + QWriteLocker writeLocker(&_nodeMutex); + _localIDMap.unsafe_erase(node->getLocalID()); + _nodeHash.unsafe_erase(node->getUUID()); + handleNodeKill(node); + } + }; + + // if this is a solo node type, we assume that the DS has replaced its assignment and we should kill the previous node + if (SOLO_NODE_TYPES.count(nodeType)) { + removeOldNode(soloNodeOfType(nodeType)); + } + // If there is a new node with the same socket, this is a reconnection, kill the old node + removeOldNode(findNodeWithAddr(publicSocket)); + removeOldNode(findNodeWithAddr(localSocket)); + + auto it = _connectionIDs.find(uuid); + if (it == _connectionIDs.end()) { + _connectionIDs[uuid] = INITIAL_CONNECTION_ID; + } + + // we didn't have this node, so add them + Node* newNode = new Node(uuid, nodeType, publicSocket, localSocket); + newNode->setIsReplicated(isReplicated); + newNode->setIsUpstream(isUpstream || NodeType::isUpstream(nodeType)); + newNode->setConnectionSecret(connectionSecret); + newNode->setPermissions(permissions); + newNode->setLocalID(localID); + + // move the newly constructed node to the LNL thread + newNode->moveToThread(thread()); + + if (nodeType == NodeType::AudioMixer) { + LimitedNodeList::flagTimeForConnectionStep(LimitedNodeList::AddedAudioMixer); + } + + SharedNodePointer newNodePointer(newNode, &QObject::deleteLater); + + + { + QReadLocker readLocker(&_nodeMutex); + // insert the new node and release our read lock + _nodeHash.insert({ newNode->getUUID(), newNodePointer }); + _localIDMap.insert({ localID, newNodePointer }); + } + + qCDebug(networking) << "Added" << *newNode; + + auto weakPtr = newNodePointer.toWeakRef(); // We don't want the lambdas to hold a strong ref + + emit nodeAdded(newNodePointer); + if (newNodePointer->getActiveSocket()) { + emit nodeActivated(newNodePointer); + } else { + connect(newNodePointer.data(), &NetworkPeer::socketActivated, this, [this, weakPtr] { + auto sharedPtr = weakPtr.lock(); + if (sharedPtr) { + emit nodeActivated(sharedPtr); + disconnect(sharedPtr.data(), &NetworkPeer::socketActivated, this, 0); + } + }); + } + + // Signal when a socket changes, so we can start the hole punch over. + connect(newNodePointer.data(), &NetworkPeer::socketUpdated, this, [this, weakPtr] { + emit nodeSocketUpdated(weakPtr); + }); + + return newNodePointer; } std::unique_ptr LimitedNodeList::constructPingPacket(const QUuid& nodeId, PingType_t pingType) { From d27d624c3f652011dea0ba4459680154846426e3 Mon Sep 17 00:00:00 2001 From: Clement Date: Fri, 22 Feb 2019 18:05:42 -0800 Subject: [PATCH 125/137] Don't send a KillAvatar packet on kick The DS already takes cares of removing nodes no longer allowed when the permissions are updated and KillAvatar was never meant to be used from the DS. --- domain-server/src/DomainServerSettingsManager.cpp | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/domain-server/src/DomainServerSettingsManager.cpp b/domain-server/src/DomainServerSettingsManager.cpp index 780fad15f2..4e833f6b77 100644 --- a/domain-server/src/DomainServerSettingsManager.cpp +++ b/domain-server/src/DomainServerSettingsManager.cpp @@ -25,13 +25,13 @@ #include #include +#include #include #include #include #include #include #include -#include //for KillAvatarReason #include #include "DomainServerNodeData.h" @@ -870,14 +870,6 @@ void DomainServerSettingsManager::processNodeKickRequestPacket(QSharedPointerwrite(nodeUUID.toRfc4122()); - packet->writePrimitive(KillAvatarReason::NoReason); - - // send to avatar mixer, it sends the kill to everyone else - limitedNodeList->broadcastToNodes(std::move(packet), NodeSet() << NodeType::AvatarMixer); - if (newPermissions) { qDebug() << "Removing connect permission for node" << uuidStringWithoutCurlyBraces(matchingNode->getUUID()) << "after kick request from" << uuidStringWithoutCurlyBraces(sendingNode->getUUID()); From 8058ad884e343d685ff72e5dff479a6afeb9cfd3 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Mon, 25 Feb 2019 09:48:41 -0800 Subject: [PATCH 126/137] trying to fix overlay rotation --- interface/src/ui/overlays/Overlays.cpp | 60 +++++++------------------- interface/src/ui/overlays/Overlays.h | 2 +- 2 files changed, 17 insertions(+), 45 deletions(-) diff --git a/interface/src/ui/overlays/Overlays.cpp b/interface/src/ui/overlays/Overlays.cpp index 62a6b88fc0..6d04c4d53a 100644 --- a/interface/src/ui/overlays/Overlays.cpp +++ b/interface/src/ui/overlays/Overlays.cpp @@ -295,14 +295,14 @@ QString Overlays::overlayToEntityType(const QString& type) { } \ } -static QHash savedRotations = QHash(); +static QHash> savedRotations = QHash>(); EntityItemProperties Overlays::convertOverlayToEntityProperties(QVariantMap& overlayProps, const QString& type, bool add, const QUuid& id) { - glm::quat rotation; + std::pair rotation; return convertOverlayToEntityProperties(overlayProps, rotation, type, add, id); } -EntityItemProperties Overlays::convertOverlayToEntityProperties(QVariantMap& overlayProps, glm::quat& rotationToSave, const QString& type, bool add, const QUuid& id) { +EntityItemProperties Overlays::convertOverlayToEntityProperties(QVariantMap& overlayProps, std::pair& rotationToSave, const QString& type, bool add, const QUuid& id) { overlayProps["type"] = type; SET_OVERLAY_PROP_DEFAULT(alpha, 0.7); @@ -559,65 +559,33 @@ EntityItemProperties Overlays::convertOverlayToEntityProperties(QVariantMap& ove SET_OVERLAY_PROP_DEFAULT(textures, PathUtils::resourcesUrl() + "images/whitePixel.png"); } - { // Overlays did this conversion for rotation - auto iter = overlayProps.find("rotation"); - if (iter != overlayProps.end() && !overlayProps.contains("localRotation")) { - QUuid parentID; - { - auto iter = overlayProps.find("parentID"); - if (iter != overlayProps.end()) { - parentID = iter.value().toUuid(); - } else if (!add) { - EntityPropertyFlags desiredProperties; - desiredProperties += PROP_PARENT_ID; - parentID = DependencyManager::get()->getEntityProperties(id, desiredProperties).getParentID(); - } - } - - int parentJointIndex = -1; - { - auto iter = overlayProps.find("parentJointIndex"); - if (iter != overlayProps.end()) { - parentJointIndex = iter.value().toInt(); - } else if (!add) { - EntityPropertyFlags desiredProperties; - desiredProperties += PROP_PARENT_JOINT_INDEX; - parentJointIndex = DependencyManager::get()->getEntityProperties(id, desiredProperties).getParentJointIndex(); - } - } - - glm::quat rotation = quatFromVariant(iter.value()); - bool success = false; - glm::quat localRotation = SpatiallyNestable::worldToLocal(rotation, parentID, parentJointIndex, false, success); - if (success) { - overlayProps["rotation"] = quatToVariant(localRotation); - } - } - } - if (type == "Text" || type == "Image" || type == "Grid" || type == "Web") { glm::quat originalRotation = ENTITY_ITEM_DEFAULT_ROTATION; + bool local = false; { auto iter = overlayProps.find("rotation"); if (iter != overlayProps.end()) { originalRotation = quatFromVariant(iter.value()); + local = false; } else { iter = overlayProps.find("localRotation"); if (iter != overlayProps.end()) { originalRotation = quatFromVariant(iter.value()); + local = true; } else if (!add) { auto iter2 = savedRotations.find(id); if (iter2 != savedRotations.end()) { - originalRotation = iter2.value(); + originalRotation = iter2.value().first; + local = iter2.value().second; } } } } if (!add) { - savedRotations[id] = originalRotation; + savedRotations[id] = { originalRotation, local }; } else { - rotationToSave = originalRotation; + rotationToSave = { originalRotation, local }; } glm::vec3 dimensions = ENTITY_ITEM_DEFAULT_DIMENSIONS; @@ -648,7 +616,11 @@ EntityItemProperties Overlays::convertOverlayToEntityProperties(QVariantMap& ove rotation = glm::angleAxis((float)M_PI, rotation * Vectors::UP) * rotation; } - overlayProps["localRotation"] = quatToVariant(rotation); + if (local) { + overlayProps["localRotation"] = quatToVariant(rotation); + } else { + overlayProps["rotation"] = quatToVariant(rotation); + } overlayProps["dimensions"] = vec3toVariant(glm::abs(dimensions)); } } @@ -826,7 +798,7 @@ QUuid Overlays::addOverlay(const QString& type, const QVariant& properties) { if (type == "rectangle3d") { propertyMap["shape"] = "Quad"; } - glm::quat rotationToSave; + std::pair rotationToSave; QUuid id = DependencyManager::get()->addEntityInternal(convertOverlayToEntityProperties(propertyMap, rotationToSave, entityType, true), entity::HostType::LOCAL); if (entityType == "Text" || entityType == "Image" || entityType == "Grid" || entityType == "Web") { savedRotations[id] = rotationToSave; diff --git a/interface/src/ui/overlays/Overlays.h b/interface/src/ui/overlays/Overlays.h index 838a38eb54..93efc2bc0b 100644 --- a/interface/src/ui/overlays/Overlays.h +++ b/interface/src/ui/overlays/Overlays.h @@ -729,7 +729,7 @@ private: QVariantMap convertEntityToOverlayProperties(const EntityItemProperties& entityProps); EntityItemProperties convertOverlayToEntityProperties(QVariantMap& overlayProps, const QString& type, bool add, const QUuid& id); - EntityItemProperties convertOverlayToEntityProperties(QVariantMap& overlayProps, glm::quat& rotationToSave, const QString& type, bool add, const QUuid& id = QUuid()); + EntityItemProperties convertOverlayToEntityProperties(QVariantMap& overlayProps, std::pair& rotationToSave, const QString& type, bool add, const QUuid& id = QUuid()); private slots: void mousePressPointerEvent(const QUuid& id, const PointerEvent& event); From db821487d9ec82f7a051699fc841cea41eceabb9 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 25 Feb 2019 11:01:21 -0800 Subject: [PATCH 127/137] don't allow others' grabs to move locked or ungrabbable things --- interface/src/avatar/GrabManager.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/interface/src/avatar/GrabManager.cpp b/interface/src/avatar/GrabManager.cpp index db1337b64d..8273def490 100644 --- a/interface/src/avatar/GrabManager.cpp +++ b/interface/src/avatar/GrabManager.cpp @@ -32,6 +32,17 @@ void GrabManager::simulateGrabs() { bool success; SpatiallyNestablePointer grabbedThing = SpatiallyNestable::findByID(grabbedThingID, success); if (success && grabbedThing) { + auto entity = std::dynamic_pointer_cast(grabbedThing); + if (entity) { + if (entity->getLocked()) { + continue; // even if someone else claims to be grabbing it, don't move a locked thing + } + const GrabPropertyGroup& grabProps = entity->getGrabProperties(); + if (!grabProps.getGrabbable()) { + continue; // even if someone else claims to be grabbing it, don't move non-grabbable + } + } + glm::vec3 finalPosition = acc.finalizePosition(); glm::quat finalOrientation = acc.finalizeOrientation(); grabbedThing->setTransform(createMatFromQuatAndPos(finalOrientation, finalPosition)); From e102ad073eca78e1598e35ff4d1d057febe67c2b Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Mon, 25 Feb 2019 11:49:38 -0800 Subject: [PATCH 128/137] allow flying in HMD if you would otherwise fall forever --- interface/src/avatar/MyAvatar.cpp | 3 ++- libraries/physics/src/CharacterController.cpp | 22 ++++++++----------- libraries/physics/src/CharacterController.h | 16 ++++++++------ 3 files changed, 20 insertions(+), 21 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index af261f490b..faa9f88ae9 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -932,7 +932,8 @@ void MyAvatar::simulate(float deltaTime, bool inView) { bool isPhysicsEnabled = qApp->isPhysicsEnabled(); bool zoneAllowsFlying = zoneInteractionProperties.first; bool collisionlessAllowed = zoneInteractionProperties.second; - _characterController.setFlyingAllowed((zoneAllowsFlying && _enableFlying) || !isPhysicsEnabled); + _characterController.setZoneFlyingAllowed(zoneAllowsFlying || !isPhysicsEnabled); + _characterController.setComfortFlyingAllowed(_enableFlying); _characterController.setCollisionlessAllowed(collisionlessAllowed); } diff --git a/libraries/physics/src/CharacterController.cpp b/libraries/physics/src/CharacterController.cpp index 66ce5f32bf..a5f1a0598f 100755 --- a/libraries/physics/src/CharacterController.cpp +++ b/libraries/physics/src/CharacterController.cpp @@ -781,18 +781,18 @@ void CharacterController::updateState() { const float jumpSpeed = sqrtf(2.0f * -DEFAULT_AVATAR_GRAVITY * jumpHeight); if ((velocity.dot(_currentUp) <= (jumpSpeed / 2.0f)) && ((_floorDistance < FLY_TO_GROUND_THRESHOLD) || _hasSupport)) { SET_STATE(State::Ground, "hit ground"); - } else if (_flyingAllowed) { + } else if (_zoneFlyingAllowed) { btVector3 desiredVelocity = _targetVelocity; if (desiredVelocity.length2() < MIN_TARGET_SPEED_SQUARED) { desiredVelocity = btVector3(0.0f, 0.0f, 0.0f); } bool vertTargetSpeedIsNonZero = desiredVelocity.dot(_currentUp) > MIN_TARGET_SPEED; - if ((jumpButtonHeld || vertTargetSpeedIsNonZero) && (_takeoffJumpButtonID != _jumpButtonDownCount)) { + if (_comfortFlyingAllowed && (jumpButtonHeld || vertTargetSpeedIsNonZero) && (_takeoffJumpButtonID != _jumpButtonDownCount)) { SET_STATE(State::Hover, "double jump button"); - } else if ((jumpButtonHeld || vertTargetSpeedIsNonZero) && (now - _jumpButtonDownStartTime) > JUMP_TO_HOVER_PERIOD) { + } else if (_comfortFlyingAllowed && (jumpButtonHeld || vertTargetSpeedIsNonZero) && (now - _jumpButtonDownStartTime) > JUMP_TO_HOVER_PERIOD) { SET_STATE(State::Hover, "jump button held"); - } else if (_floorDistance > _scaleFactor * DEFAULT_AVATAR_FALL_HEIGHT) { - // Transition to hover if we are above the fall threshold + } else if ((!rayHasHit && !_hasSupport) || _floorDistance > _scaleFactor * DEFAULT_AVATAR_FALL_HEIGHT) { + // Transition to hover if there's no ground beneath us or we are above the fall threshold, regardless of _comfortFlyingAllowed SET_STATE(State::Hover, "above fall threshold"); } } @@ -801,8 +801,10 @@ void CharacterController::updateState() { case State::Hover: btScalar horizontalSpeed = (velocity - velocity.dot(_currentUp) * _currentUp).length(); bool flyingFast = horizontalSpeed > (MAX_WALKING_SPEED * 0.75f); - if (!_flyingAllowed) { - SET_STATE(State::InAir, "flying not allowed"); + if (!_zoneFlyingAllowed) { + SET_STATE(State::InAir, "zone flying not allowed"); + } else if (!_comfortFlyingAllowed && (rayHasHit || _hasSupport || _floorDistance < FLY_TO_GROUND_THRESHOLD)) { + SET_STATE(State::InAir, "comfort flying not allowed"); } else if ((_floorDistance < MIN_HOVER_HEIGHT) && !jumpButtonHeld && !flyingFast) { SET_STATE(State::InAir, "near ground"); } else if (((_floorDistance < FLY_TO_GROUND_THRESHOLD) || _hasSupport) && !flyingFast) { @@ -847,12 +849,6 @@ bool CharacterController::getRigidBodyLocation(glm::vec3& avatarRigidBodyPositio return true; } -void CharacterController::setFlyingAllowed(bool value) { - if (value != _flyingAllowed) { - _flyingAllowed = value; - } -} - void CharacterController::setCollisionlessAllowed(bool value) { if (value != _collisionlessAllowed) { _collisionlessAllowed = value; diff --git a/libraries/physics/src/CharacterController.h b/libraries/physics/src/CharacterController.h index d59374a94a..c46c9c8361 100755 --- a/libraries/physics/src/CharacterController.h +++ b/libraries/physics/src/CharacterController.h @@ -65,10 +65,10 @@ public: // overrides from btCharacterControllerInterface virtual void setWalkDirection(const btVector3 &walkDirection) override { assert(false); } virtual void setVelocityForTimeInterval(const btVector3 &velocity, btScalar timeInterval) override { assert(false); } - virtual void reset(btCollisionWorld* collisionWorld) override { } - virtual void warp(const btVector3& origin) override { } - virtual void debugDraw(btIDebugDraw* debugDrawer) override { } - virtual void setUpInterpolate(bool value) override { } + virtual void reset(btCollisionWorld* collisionWorld) override {} + virtual void warp(const btVector3& origin) override {} + virtual void debugDraw(btIDebugDraw* debugDrawer) override {} + virtual void setUpInterpolate(bool value) override {} virtual void updateAction(btCollisionWorld* collisionWorld, btScalar deltaTime) override; virtual void preStep(btCollisionWorld *collisionWorld) override; virtual void playerStep(btCollisionWorld *collisionWorld, btScalar dt) override; @@ -90,7 +90,7 @@ public: void preSimulation(); void postSimulation(); - void setPositionAndOrientation( const glm::vec3& position, const glm::quat& orientation); + void setPositionAndOrientation(const glm::vec3& position, const glm::quat& orientation); void getPositionAndOrientation(glm::vec3& position, glm::quat& rotation) const; void setParentVelocity(const glm::vec3& parentVelocity); @@ -129,7 +129,8 @@ public: bool getRigidBodyLocation(glm::vec3& avatarRigidBodyPosition, glm::quat& avatarRigidBodyRotation); - void setFlyingAllowed(bool value); + void setZoneFlyingAllowed(bool value) { _zoneFlyingAllowed = value; } + void setComfortFlyingAllowed(bool value) { _comfortFlyingAllowed = value; } void setCollisionlessAllowed(bool value); void setPendingFlagsUpdateCollisionMask(){ _pendingFlags |= PENDING_FLAG_UPDATE_COLLISION_MASK; } @@ -212,7 +213,8 @@ protected: uint32_t _pendingFlags { 0 }; uint32_t _previousFlags { 0 }; - bool _flyingAllowed { true }; + bool _zoneFlyingAllowed { true }; + bool _comfortFlyingAllowed { true }; bool _collisionlessAllowed { true }; bool _collisionless { false }; From cff0fd470a43020148f0baf5fa8dc92d4a74a198 Mon Sep 17 00:00:00 2001 From: amantley Date: Mon, 25 Feb 2019 12:23:03 -0800 Subject: [PATCH 129/137] re-enabled ik off by default on Desktop --- libraries/animation/src/Rig.cpp | 44 +++++++++++++++++---------------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index fcf2cd28a3..372f03c163 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -1064,28 +1064,30 @@ void Rig::computeMotionAnimationState(float deltaTime, const glm::vec3& worldPos t += deltaTime; - if (_enableInverseKinematics) { - _animVars.set("ikOverlayAlpha", 1.0f); - _animVars.set("splineIKEnabled", true); - _animVars.set("leftHandIKEnabled", true); - _animVars.set("rightHandIKEnabled", true); - _animVars.set("leftFootIKEnabled", true); - _animVars.set("rightFootIKEnabled", true); - _animVars.set("leftFootPoleVectorEnabled", true); - _animVars.set("rightFootPoleVectorEnabled", true); - } else { - _animVars.set("ikOverlayAlpha", 0.0f); - _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); + if (_enableInverseKinematics != _lastEnableInverseKinematics) { + if (_enableInverseKinematics) { + _animVars.set("ikOverlayAlpha", 1.0f); + _animVars.set("splineIKEnabled", true); + _animVars.set("leftHandIKEnabled", true); + _animVars.set("rightHandIKEnabled", true); + _animVars.set("leftFootIKEnabled", true); + _animVars.set("rightFootIKEnabled", true); + _animVars.set("leftFootPoleVectorEnabled", true); + _animVars.set("rightFootPoleVectorEnabled", true); + } else { + _animVars.set("ikOverlayAlpha", 0.0f); + _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; } - _lastEnableInverseKinematics = _enableInverseKinematics; } _lastForward = forward; _lastPosition = worldPosition; From 363c0cc26f55a7573f997cc8c0dfe91459b3d87b Mon Sep 17 00:00:00 2001 From: amantley Date: Mon, 25 Feb 2019 13:03:28 -0800 Subject: [PATCH 130/137] moved the update of last ik to outside the if changed statement --- libraries/animation/src/Rig.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index 372f03c163..fb7bb15341 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -1086,8 +1086,8 @@ void Rig::computeMotionAnimationState(float deltaTime, const glm::vec3& worldPos _animVars.set("leftFootPoleVectorEnabled", false); _animVars.set("rightFootPoleVectorEnabled", false); } - _lastEnableInverseKinematics = _enableInverseKinematics; } + _lastEnableInverseKinematics = _enableInverseKinematics; } _lastForward = forward; _lastPosition = worldPosition; From 12dbaa0ea0698ebe4798605956e15695f0896e74 Mon Sep 17 00:00:00 2001 From: amantley Date: Mon, 25 Feb 2019 14:56:03 -0800 Subject: [PATCH 131/137] changed the condition so that you can turn off ik in hmd mode if you want to for debug purposes --- libraries/animation/src/Rig.cpp | 35 ++++++++++++--------------------- 1 file changed, 13 insertions(+), 22 deletions(-) diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index fb7bb15341..25f154e9fd 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -1064,28 +1064,19 @@ void Rig::computeMotionAnimationState(float deltaTime, const glm::vec3& worldPos t += deltaTime; - if (_enableInverseKinematics != _lastEnableInverseKinematics) { - if (_enableInverseKinematics) { - _animVars.set("ikOverlayAlpha", 1.0f); - _animVars.set("splineIKEnabled", true); - _animVars.set("leftHandIKEnabled", true); - _animVars.set("rightHandIKEnabled", true); - _animVars.set("leftFootIKEnabled", true); - _animVars.set("rightFootIKEnabled", true); - _animVars.set("leftFootPoleVectorEnabled", true); - _animVars.set("rightFootPoleVectorEnabled", true); - } else { - _animVars.set("ikOverlayAlpha", 0.0f); - _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); - } + if (_enableInverseKinematics) { + _animVars.set("ikOverlayAlpha", 1.0f); + } else { + _animVars.set("ikOverlayAlpha", 0.0f); + _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; } From f235d046013de90509d629f7542c97423e6f559c Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Mon, 25 Feb 2019 15:06:11 -0800 Subject: [PATCH 132/137] trying to fix web crashes --- .../src/RenderableWebEntityItem.cpp | 142 ++++++++++-------- .../src/RenderableWebEntityItem.h | 1 + 2 files changed, 79 insertions(+), 64 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableWebEntityItem.cpp b/libraries/entities-renderer/src/RenderableWebEntityItem.cpp index ccd815b74a..0f2c708d17 100644 --- a/libraries/entities-renderer/src/RenderableWebEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableWebEntityItem.cpp @@ -101,21 +101,15 @@ bool WebEntityRenderer::isTransparent() const { } bool WebEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const { - if (_contextPosition != entity->getWorldPosition()) { - return true; - } - - { - QSharedPointer webSurface; - withReadLock([&] { - webSurface = _webSurface; - }); - if (webSurface && uvec2(getWindowSize(entity)) != toGlm(webSurface->size())) { + if (resultWithReadLock([&] { + if (_webSurface && uvec2(getWindowSize(entity)) != toGlm(_webSurface->size())) { + return true; + } + + if (_contextPosition != entity->getWorldPosition()) { return true; } - } - if(resultWithReadLock([&] { if (_color != entity->getColor()) { return true; } @@ -194,7 +188,7 @@ void WebEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene auto newContentType = getContentType(newSourceURL); ContentType currentContentType; withReadLock([&] { - urlChanged = _sourceURL != newSourceURL; + urlChanged = newSourceURL.isEmpty() || newSourceURL != _tryingToBuildURL; }); currentContentType = _contentType; @@ -206,7 +200,6 @@ void WebEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene } } - withWriteLock([&] { _inputMode = entity->getInputMode(); _dpi = entity->getDPI(); @@ -216,6 +209,8 @@ void WebEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene _billboardMode = entity->getBillboardMode(); if (_contentType == ContentType::NoContent) { + _tryingToBuildURL = newSourceURL; + _sourceURL = newSourceURL; return; } @@ -226,10 +221,12 @@ void WebEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene if (_webSurface) { if (_webSurface->getRootItem()) { - if (_contentType == ContentType::HtmlContent && urlChanged) { + if (_contentType == ContentType::HtmlContent && _sourceURL != newSourceURL) { _webSurface->getRootItem()->setProperty(URL_PROPERTY, newSourceURL); + _sourceURL = newSourceURL; + } else if (_contentType != ContentType::HtmlContent) { + _sourceURL = newSourceURL; } - _sourceURL = newSourceURL; { auto scriptURL = entity->getScriptURL(); @@ -294,20 +291,21 @@ void WebEntityRenderer::doRender(RenderArgs* args) { }); // Try to update the texture - { - QSharedPointer webSurface; - withReadLock([&] { - webSurface = _webSurface; - }); - if (!webSurface) { - return; + OffscreenQmlSurface::TextureAndFence newTextureAndFence; + bool newTextureAvailable = false; + if (!resultWithReadLock([&] { + if (!_webSurface) { + return false; } - OffscreenQmlSurface::TextureAndFence newTextureAndFence; - bool newTextureAvailable = webSurface->fetchTexture(newTextureAndFence); - if (newTextureAvailable) { - _texture->setExternalTexture(newTextureAndFence.first, newTextureAndFence.second); - } + newTextureAvailable = _webSurface->fetchTexture(newTextureAndFence); + return true; + })) { + return; + } + + if (newTextureAvailable) { + _texture->setExternalTexture(newTextureAndFence.first, newTextureAndFence.second); } static const glm::vec2 texMin(0.0f), texMax(1.0f), topLeft(-0.5f), bottomRight(0.5f); @@ -351,6 +349,8 @@ void WebEntityRenderer::buildWebSurface(const EntityItemPointer& entity, const Q _connections.push_back(QObject::connect(_webSurface.data(), &OffscreenQmlSurface::webEventReceived, this, [entityItemID](const QVariant& message) { emit DependencyManager::get()->webEventReceived(entityItemID, message); })); + + _tryingToBuildURL = newSourceURL; } void WebEntityRenderer::destroyWebSurface() { @@ -383,11 +383,16 @@ glm::vec2 WebEntityRenderer::getWindowSize(const TypedEntityPointer& entity) con void WebEntityRenderer::hoverEnterEntity(const PointerEvent& event) { if (_inputMode == WebInputMode::MOUSE) { handlePointerEvent(event); - } else if (_webSurface) { - PointerEvent webEvent = event; - webEvent.setPos2D(event.getPos2D() * (METERS_TO_INCHES * _dpi)); - _webSurface->hoverBeginEvent(webEvent, _touchDevice); + return; } + + withReadLock([&] { + if (_webSurface) { + PointerEvent webEvent = event; + webEvent.setPos2D(event.getPos2D() * (METERS_TO_INCHES * _dpi)); + _webSurface->hoverBeginEvent(webEvent, _touchDevice); + } + }); } void WebEntityRenderer::hoverLeaveEntity(const PointerEvent& event) { @@ -398,34 +403,39 @@ void WebEntityRenderer::hoverLeaveEntity(const PointerEvent& event) { // QML onReleased is only triggered if a click has happened first. We need to send this "fake" mouse move event to properly trigger an onExited. PointerEvent endMoveEvent(PointerEvent::Move, event.getID()); handlePointerEvent(endMoveEvent); - } else if (_webSurface) { - PointerEvent webEvent = event; - webEvent.setPos2D(event.getPos2D() * (METERS_TO_INCHES * _dpi)); - _webSurface->hoverEndEvent(webEvent, _touchDevice); - } -} - -void WebEntityRenderer::handlePointerEvent(const PointerEvent& event) { - if (_inputMode == WebInputMode::TOUCH) { - handlePointerEventAsTouch(event); - } else { - handlePointerEventAsMouse(event); - } -} - -void WebEntityRenderer::handlePointerEventAsTouch(const PointerEvent& event) { - if (_webSurface) { - PointerEvent webEvent = event; - webEvent.setPos2D(event.getPos2D() * (METERS_TO_INCHES * _dpi)); - _webSurface->handlePointerEvent(webEvent, _touchDevice); - } -} - -void WebEntityRenderer::handlePointerEventAsMouse(const PointerEvent& event) { - if (!_webSurface) { return; } + withReadLock([&] { + if (_webSurface) { + PointerEvent webEvent = event; + webEvent.setPos2D(event.getPos2D() * (METERS_TO_INCHES * _dpi)); + _webSurface->hoverEndEvent(webEvent, _touchDevice); + } + }); +} + +void WebEntityRenderer::handlePointerEvent(const PointerEvent& event) { + withReadLock([&] { + if (!_webSurface) { + return; + } + + if (_inputMode == WebInputMode::TOUCH) { + handlePointerEventAsTouch(event); + } else { + handlePointerEventAsMouse(event); + } + }); +} + +void WebEntityRenderer::handlePointerEventAsTouch(const PointerEvent& event) { + PointerEvent webEvent = event; + webEvent.setPos2D(event.getPos2D() * (METERS_TO_INCHES * _dpi)); + _webSurface->handlePointerEvent(webEvent, _touchDevice); +} + +void WebEntityRenderer::handlePointerEventAsMouse(const PointerEvent& event) { glm::vec2 windowPos = event.getPos2D() * (METERS_TO_INCHES * _dpi); QPointF windowPoint(windowPos.x, windowPos.y); @@ -459,16 +469,20 @@ void WebEntityRenderer::handlePointerEventAsMouse(const PointerEvent& event) { } void WebEntityRenderer::setProxyWindow(QWindow* proxyWindow) { - if (_webSurface) { - _webSurface->setProxyWindow(proxyWindow); - } + withReadLock([&] { + if (_webSurface) { + _webSurface->setProxyWindow(proxyWindow); + } + }); } QObject* WebEntityRenderer::getEventHandler() { - if (!_webSurface) { - return nullptr; - } - return _webSurface->getEventHandler(); + return resultWithReadLock([&]() -> QObject* { + if (!_webSurface) { + return nullptr; + } + return _webSurface->getEventHandler(); + }); } void WebEntityRenderer::emitScriptEvent(const QVariant& message) { diff --git a/libraries/entities-renderer/src/RenderableWebEntityItem.h b/libraries/entities-renderer/src/RenderableWebEntityItem.h index 30b63a72df..0345898b62 100644 --- a/libraries/entities-renderer/src/RenderableWebEntityItem.h +++ b/libraries/entities-renderer/src/RenderableWebEntityItem.h @@ -82,6 +82,7 @@ private: QSharedPointer _webSurface { nullptr }; bool _cachedWebSurface { false }; gpu::TexturePointer _texture; + QString _tryingToBuildURL; glm::u8vec3 _color; float _alpha { 1.0f }; From 6e4ec15c9de9e19a808191fd11e0aafd58cd63c1 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Mon, 25 Feb 2019 17:14:51 -0800 Subject: [PATCH 133/137] there we go --- libraries/render-utils/src/RenderPipelines.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/libraries/render-utils/src/RenderPipelines.cpp b/libraries/render-utils/src/RenderPipelines.cpp index 83216ddf84..c4a7368f39 100644 --- a/libraries/render-utils/src/RenderPipelines.cpp +++ b/libraries/render-utils/src/RenderPipelines.cpp @@ -731,10 +731,6 @@ void RenderPipelines::updateMultiMaterial(graphics::MultiMaterial& multiMaterial } void RenderPipelines::bindMaterials(graphics::MultiMaterial& multiMaterial, gpu::Batch& batch, bool enableTextures) { - if (multiMaterial.size() == 0) { - return; - } - if (multiMaterial.shouldUpdate()) { updateMultiMaterial(multiMaterial); } From 4d591e0624081af7ff589f64bb0cb0c3d956f5a1 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Tue, 26 Feb 2019 16:12:12 -0800 Subject: [PATCH 134/137] fix web interaction and debug print filling logs --- .../entities/src/MovingEntitiesOperator.cpp | 6 +- .../system/libraries/entitySelectionTool.js | 107 ++++++++++-------- 2 files changed, 62 insertions(+), 51 deletions(-) diff --git a/libraries/entities/src/MovingEntitiesOperator.cpp b/libraries/entities/src/MovingEntitiesOperator.cpp index 4b908745e0..9dd5a4d206 100644 --- a/libraries/entities/src/MovingEntitiesOperator.cpp +++ b/libraries/entities/src/MovingEntitiesOperator.cpp @@ -55,13 +55,11 @@ void MovingEntitiesOperator::addEntityToMoveList(EntityItemPointer entity, const qCDebug(entities) << " oldContainingElement->bestFitBounds(newCubeClamped):" << oldContainingElement->bestFitBounds(newCubeClamped); } else { - qCDebug(entities) << " WARNING NO OLD CONTAINING ELEMENT!!!"; + qCDebug(entities) << " WARNING NO OLD CONTAINING ELEMENT for entity" << entity->getEntityItemID(); } } - + if (!oldContainingElement) { - qCDebug(entities) << "UNEXPECTED!!!! attempting to move entity "<< entity->getEntityItemID() - << "that has no containing element. "; return; // bail without adding. } diff --git a/scripts/system/libraries/entitySelectionTool.js b/scripts/system/libraries/entitySelectionTool.js index 767128ca16..269283ea6d 100644 --- a/scripts/system/libraries/entitySelectionTool.js +++ b/scripts/system/libraries/entitySelectionTool.js @@ -708,7 +708,7 @@ SelectionDisplay = (function() { shape: "Cone", solid: true, visible: false, - ignoreRayIntersection: false, + ignorePickIntersection: true, drawInFront: true }; var handlePropertiesTranslateArrowCylinders = { @@ -716,7 +716,7 @@ SelectionDisplay = (function() { shape: "Cylinder", solid: true, visible: false, - ignoreRayIntersection: false, + ignorePickIntersection: true, drawInFront: true }; var handleTranslateXCone = Overlays.addOverlay("shape", handlePropertiesTranslateArrowCones); @@ -741,7 +741,7 @@ SelectionDisplay = (function() { majorTickMarksAngle: ROTATE_DEFAULT_TICK_MARKS_ANGLE, majorTickMarksLength: 0.1, visible: false, - ignoreRayIntersection: false, + ignorePickIntersection: true, drawInFront: true }; var handleRotatePitchRing = Overlays.addOverlay("circle3d", handlePropertiesRotateRings); @@ -766,7 +766,7 @@ SelectionDisplay = (function() { solid: true, innerRadius: 0.9, visible: false, - ignoreRayIntersection: true, + ignorePickIntersection: true, drawInFront: true }); @@ -779,7 +779,7 @@ SelectionDisplay = (function() { visible: false, isFacingAvatar: true, drawInFront: true, - ignoreRayIntersection: true, + ignorePickIntersection: true, dimensions: { x: 0, y: 0 }, lineHeight: 0.0, topMargin: 0, @@ -791,7 +791,7 @@ SelectionDisplay = (function() { var handlePropertiesStretchCubes = { solid: true, visible: false, - ignoreRayIntersection: false, + ignorePickIntersection: true, drawInFront: true }; var handleStretchXCube = Overlays.addOverlay("cube", handlePropertiesStretchCubes); @@ -802,18 +802,17 @@ SelectionDisplay = (function() { Overlays.editOverlay(handleStretchZCube, { color: COLOR_BLUE }); var handlePropertiesStretchPanel = { - shape: "Quad", alpha: 0.5, solid: true, visible: false, - ignoreRayIntersection: true, + ignorePickIntersection: true, drawInFront: true }; - var handleStretchXPanel = Overlays.addOverlay("shape", handlePropertiesStretchPanel); + var handleStretchXPanel = Overlays.addOverlay("cube", handlePropertiesStretchPanel); Overlays.editOverlay(handleStretchXPanel, { color: COLOR_RED }); - var handleStretchYPanel = Overlays.addOverlay("shape", handlePropertiesStretchPanel); + var handleStretchYPanel = Overlays.addOverlay("cube", handlePropertiesStretchPanel); Overlays.editOverlay(handleStretchYPanel, { color: COLOR_GREEN }); - var handleStretchZPanel = Overlays.addOverlay("shape", handlePropertiesStretchPanel); + var handleStretchZPanel = Overlays.addOverlay("cube", handlePropertiesStretchPanel); Overlays.editOverlay(handleStretchZPanel, { color: COLOR_BLUE }); var handleScaleCube = Overlays.addOverlay("cube", { @@ -821,7 +820,7 @@ SelectionDisplay = (function() { color: COLOR_SCALE_CUBE, solid: true, visible: false, - ignoreRayIntersection: false, + ignorePickIntersection: true, drawInFront: true, borderSize: 1.4 }); @@ -841,7 +840,7 @@ SelectionDisplay = (function() { color: COLOR_GREEN, solid: true, visible: false, - ignoreRayIntersection: false, + ignorePickIntersection: true, drawInFront: true, borderSize: 1.4 }); @@ -854,6 +853,7 @@ SelectionDisplay = (function() { alpha: 0, solid: false, visible: false, + ignorePickIntersection: true, dashed: false }); @@ -865,6 +865,7 @@ SelectionDisplay = (function() { alpha: 0, solid: false, visible: false, + ignorePickIntersection: true, dashed: false }); @@ -877,7 +878,7 @@ SelectionDisplay = (function() { green: 0, blue: 0 }, - ignoreRayIntersection: true // always ignore this + ignorePickIntersection: true // always ignore this }); var yRailOverlay = Overlays.addOverlay("line3d", { visible: false, @@ -888,7 +889,7 @@ SelectionDisplay = (function() { green: 255, blue: 0 }, - ignoreRayIntersection: true // always ignore this + ignorePickIntersection: true // always ignore this }); var zRailOverlay = Overlays.addOverlay("line3d", { visible: false, @@ -899,7 +900,7 @@ SelectionDisplay = (function() { green: 0, blue: 255 }, - ignoreRayIntersection: true // always ignore this + ignorePickIntersection: true // always ignore this }); var allOverlays = [ @@ -972,7 +973,7 @@ SelectionDisplay = (function() { color: COLOR_DEBUG_PICK_PLANE, solid: true, visible: false, - ignoreRayIntersection: true, + ignorePickIntersection: true, drawInFront: false }); var debugPickPlaneHits = []; @@ -1802,6 +1803,7 @@ SelectionDisplay = (function() { isActiveTool(handleRotateYawRing) || isActiveTool(handleRotateRollRing); selectionBoxGeometry.visible = !inModeRotate && !isCameraInsideBox; + selectionBoxGeometry.ignorePickIntersection = !selectionBoxGeometry.visible; Overlays.editOverlay(selectionBox, selectionBoxGeometry); // UPDATE ICON TRANSLATE HANDLE @@ -1811,9 +1813,13 @@ SelectionDisplay = (function() { rotation: rotation }; iconSelectionBoxGeometry.visible = !inModeRotate && isCameraInsideBox; + iconSelectionBoxGeometry.ignorePickIntersection = !iconSelectionBoxGeometry.visible; Overlays.editOverlay(iconSelectionBox, iconSelectionBoxGeometry); } else { - Overlays.editOverlay(iconSelectionBox, { visible: false }); + Overlays.editOverlay(iconSelectionBox, { + visible: false, + ignorePickIntersection: true + }); } // UPDATE DUPLICATOR (CURRENTLY HIDDEN FOR NOW) @@ -1882,7 +1888,7 @@ SelectionDisplay = (function() { // FUNCTION: SET OVERLAYS VISIBLE that.setOverlaysVisible = function(isVisible) { for (var i = 0, length = allOverlays.length; i < length; i++) { - Overlays.editOverlay(allOverlays[i], { visible: isVisible }); + Overlays.editOverlay(allOverlays[i], { visible: isVisible, ignorePickIntersection: !isVisible }); } }; @@ -1894,18 +1900,18 @@ SelectionDisplay = (function() { }; that.setHandleTranslateXVisible = function(isVisible) { - Overlays.editOverlay(handleTranslateXCone, { visible: isVisible }); - Overlays.editOverlay(handleTranslateXCylinder, { visible: isVisible }); + Overlays.editOverlay(handleTranslateXCone, { visible: isVisible, ignorePickIntersection: !isVisible }); + Overlays.editOverlay(handleTranslateXCylinder, { visible: isVisible, ignorePickIntersection: !isVisible }); }; that.setHandleTranslateYVisible = function(isVisible) { - Overlays.editOverlay(handleTranslateYCone, { visible: isVisible }); - Overlays.editOverlay(handleTranslateYCylinder, { visible: isVisible }); + Overlays.editOverlay(handleTranslateYCone, { visible: isVisible, ignorePickIntersection: !isVisible }); + Overlays.editOverlay(handleTranslateYCylinder, { visible: isVisible, ignorePickIntersection: !isVisible }); }; that.setHandleTranslateZVisible = function(isVisible) { - Overlays.editOverlay(handleTranslateZCone, { visible: isVisible }); - Overlays.editOverlay(handleTranslateZCylinder, { visible: isVisible }); + Overlays.editOverlay(handleTranslateZCone, { visible: isVisible, ignorePickIntersection: !isVisible }); + Overlays.editOverlay(handleTranslateZCylinder, { visible: isVisible, ignorePickIntersection: !isVisible }); }; // FUNCTION: SET HANDLE ROTATE VISIBLE @@ -1916,15 +1922,15 @@ SelectionDisplay = (function() { }; that.setHandleRotatePitchVisible = function(isVisible) { - Overlays.editOverlay(handleRotatePitchRing, { visible: isVisible }); + Overlays.editOverlay(handleRotatePitchRing, { visible: isVisible, ignorePickIntersection: !isVisible }); }; that.setHandleRotateYawVisible = function(isVisible) { - Overlays.editOverlay(handleRotateYawRing, { visible: isVisible }); + Overlays.editOverlay(handleRotateYawRing, { visible: isVisible, ignorePickIntersection: !isVisible }); }; that.setHandleRotateRollVisible = function(isVisible) { - Overlays.editOverlay(handleRotateRollRing, { visible: isVisible }); + Overlays.editOverlay(handleRotateRollRing, { visible: isVisible, ignorePickIntersection: !isVisible }); }; // FUNCTION: SET HANDLE STRETCH VISIBLE @@ -1935,15 +1941,15 @@ SelectionDisplay = (function() { }; that.setHandleStretchXVisible = function(isVisible) { - Overlays.editOverlay(handleStretchXCube, { visible: isVisible }); + Overlays.editOverlay(handleStretchXCube, { visible: isVisible, ignorePickIntersection: !isVisible }); }; that.setHandleStretchYVisible = function(isVisible) { - Overlays.editOverlay(handleStretchYCube, { visible: isVisible }); + Overlays.editOverlay(handleStretchYCube, { visible: isVisible, ignorePickIntersection: !isVisible }); }; that.setHandleStretchZVisible = function(isVisible) { - Overlays.editOverlay(handleStretchZCube, { visible: isVisible }); + Overlays.editOverlay(handleStretchZCube, { visible: isVisible, ignorePickIntersection: !isVisible }); }; // FUNCTION: SET HANDLE SCALE VISIBLE @@ -1953,16 +1959,16 @@ SelectionDisplay = (function() { }; that.setHandleScaleVisible = function(isVisible) { - Overlays.editOverlay(handleScaleCube, { visible: isVisible }); + Overlays.editOverlay(handleScaleCube, { visible: isVisible, ignorePickIntersection: !isVisible }); }; that.setHandleBoundingBoxVisible = function(isVisible) { - Overlays.editOverlay(handleBoundingBox, { visible: isVisible }); + Overlays.editOverlay(handleBoundingBox, { visible: isVisible, ignorePickIntersection: true }); }; // FUNCTION: SET HANDLE DUPLICATOR VISIBLE that.setHandleDuplicatorVisible = function(isVisible) { - Overlays.editOverlay(handleDuplicator, { visible: isVisible }); + Overlays.editOverlay(handleDuplicator, { visible: isVisible, ignorePickIntersection: !isVisible }); }; // FUNCTION: DEBUG PICK PLANE @@ -1975,7 +1981,7 @@ SelectionDisplay = (function() { position: pickPlanePosition, rotation: rotation, dimensions: dimensions, - visible: true + visible: true }); }; @@ -1986,7 +1992,7 @@ SelectionDisplay = (function() { shape: "Sphere", solid: true, visible: true, - ignoreRayIntersection: true, + ignorePickIntersection: true, drawInFront: false, color: COLOR_DEBUG_PICK_PLANE_HIT, position: pickHitPosition, @@ -2082,10 +2088,12 @@ SelectionDisplay = (function() { pushCommandForSelections(duplicatedEntityIDs); if (isConstrained) { Overlays.editOverlay(xRailOverlay, { - visible: false + visible: false, + ignorePickIntersection: true }); Overlays.editOverlay(zRailOverlay, { - visible: false + visible: false, + ignorePickIntersection: true }); } }, @@ -2174,22 +2182,26 @@ SelectionDisplay = (function() { Overlays.editOverlay(xRailOverlay, { start: xStart, end: xEnd, - visible: true + visible: true, + ignorePickIntersection: true }); Overlays.editOverlay(zRailOverlay, { start: zStart, end: zEnd, - visible: true + visible: true, + ignorePickIntersection: true }); isConstrained = true; } } else { if (isConstrained) { Overlays.editOverlay(xRailOverlay, { - visible: false + visible: false, + ignorePickIntersection: true }); Overlays.editOverlay(zRailOverlay, { - visible: false + visible: false, + ignorePickIntersection: true }); isConstrained = false; } @@ -2460,7 +2472,7 @@ SelectionDisplay = (function() { } if (stretchPanel !== null) { - Overlays.editOverlay(stretchPanel, { visible: true }); + Overlays.editOverlay(stretchPanel, { visible: true, ignorePickIntersection: false }); } var stretchCubePosition = Overlays.getProperty(handleStretchCube, "position"); var stretchPanelPosition = Overlays.getProperty(stretchPanel, "position"); @@ -2481,7 +2493,7 @@ SelectionDisplay = (function() { } if (stretchPanel !== null) { - Overlays.editOverlay(stretchPanel, { visible: false }); + Overlays.editOverlay(stretchPanel, { visible: false, ignorePickIntersection: true }); } activeStretchCubePanelOffset = null; @@ -2775,7 +2787,8 @@ SelectionDisplay = (function() { rotation: worldRotation, startAt: 0, endAt: 0, - visible: true + visible: true, + ignorePickIntersection: false }); // editOverlays may not have committed rotation changes. @@ -2805,13 +2818,13 @@ SelectionDisplay = (function() { if (wantDebug) { print("================== " + getMode() + "(addHandleRotateTool onEnd) -> ======================="); } - Overlays.editOverlay(rotationDegreesDisplay, { visible: false }); + Overlays.editOverlay(rotationDegreesDisplay, { visible: false, ignorePickIntersection: true }); Overlays.editOverlay(selectedHandle, { hasTickMarks: false, solid: true, innerRadius: ROTATE_RING_IDLE_INNER_RADIUS }); - Overlays.editOverlay(handleRotateCurrentRing, { visible: false }); + Overlays.editOverlay(handleRotateCurrentRing, { visible: false, ignorePickIntersection: true }); pushCommandForSelections(); if (wantDebug) { print("================== " + getMode() + "(addHandleRotateTool onEnd) <- ======================="); From 2fd94c6bbcf61d24b047bad5fc0bd35357f35850 Mon Sep 17 00:00:00 2001 From: danteruiz Date: Tue, 26 Feb 2019 15:37:31 -0800 Subject: [PATCH 135/137] fixing login dialog --- interface/src/Application.cpp | 16 ++++++++++++++-- interface/src/Application.h | 1 + 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 83b287b7ae..ebc1176ee1 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -4979,6 +4979,15 @@ void Application::idle() { } } + { + if (_keyboardFocusWaitingOnRenderable && getEntities()->renderableForEntityId(_keyboardFocusedEntity.get())) { + _keyboardFocusWaitingOnRenderable = false; + QUuid entityId = _keyboardFocusedEntity.get(); + setKeyboardFocusEntity(UNKNOWN_ENTITY_ID); + setKeyboardFocusEntity(entityId); + } + } + { PerformanceTimer perfTimer("pluginIdle"); PerformanceWarning warn(showWarnings, "Application::idle()... pluginIdle()"); @@ -5807,7 +5816,7 @@ void Application::setKeyboardFocusEntity(const QUuid& id) { if (qApp->getLoginDialogPoppedUp() && !_loginDialogID.isNull()) { if (id == _loginDialogID) { emit loginDialogFocusEnabled(); - } else { + } else if (!_keyboardFocusWaitingOnRenderable) { // that's the only entity we want in focus; return; } @@ -5824,7 +5833,10 @@ void Application::setKeyboardFocusEntity(const QUuid& id) { if (properties.getVisible()) { auto entities = getEntities(); auto entityId = _keyboardFocusedEntity.get(); - if (entities->wantsKeyboardFocus(entityId)) { + auto entityItemRenderable = entities->renderableForEntityId(entityId); + if (!entityItemRenderable) { + _keyboardFocusWaitingOnRenderable = true; + } else if (entityItemRenderable->wantsKeyboardFocus()) { entities->setProxyWindow(entityId, _window->windowHandle()); if (_keyboardMouseDevice->isActive()) { _keyboardMouseDevice->pluginFocusOutEvent(); diff --git a/interface/src/Application.h b/interface/src/Application.h index afd9f5f12f..c16f260192 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -732,6 +732,7 @@ private: bool _failedToConnectToEntityServer { false }; bool _reticleClickPressed { false }; + bool _keyboardFocusWaitingOnRenderable { false }; int _avatarAttachmentRequest = 0; From bf9e5b9550ce622e39ddbaff655efacb952f73a8 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Wed, 27 Feb 2019 10:14:28 -0800 Subject: [PATCH 136/137] comment out another log --- interface/src/octree/SafeLanding.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/src/octree/SafeLanding.cpp b/interface/src/octree/SafeLanding.cpp index 9efad22d09..e56ca984e0 100644 --- a/interface/src/octree/SafeLanding.cpp +++ b/interface/src/octree/SafeLanding.cpp @@ -72,7 +72,7 @@ void SafeLanding::addTrackedEntity(const EntityItemID& entityID) { Locker lock(_lock); EntityItemPointer entity = _entityTree->findEntityByID(entityID); - if (entity && entity->getCreated() < _startTime) { + if (entity && !entity->isLocalEntity() && entity->getCreated() < _startTime) { _trackedEntities.emplace(entityID, entity); int trackedEntityCount = (int)_trackedEntities.size(); @@ -81,7 +81,7 @@ void SafeLanding::addTrackedEntity(const EntityItemID& entityID) { _maxTrackedEntityCount = trackedEntityCount; _trackedEntityStabilityCount = 0; } - qCDebug(interfaceapp) << "Safe Landing: Tracking entity " << entity->getItemName(); + //qCDebug(interfaceapp) << "Safe Landing: Tracking entity " << entity->getItemName(); } } } From b5f590063364a41f24662929140c7e2d02e04ed0 Mon Sep 17 00:00:00 2001 From: Anthony Thibault Date: Tue, 12 Feb 2019 11:49:30 -0800 Subject: [PATCH 137/137] Replace animation scale with scale from avatar default pose This allows avatars to have scale on their joints without being clobbered by animations. Renamed variables for easier maintenance. Also small optimization when no ikNode is present. --- libraries/animation/src/AnimClip.cpp | 83 ++++++++++++++-------------- libraries/animation/src/Rig.cpp | 18 +++--- 2 files changed, 51 insertions(+), 50 deletions(-) diff --git a/libraries/animation/src/AnimClip.cpp b/libraries/animation/src/AnimClip.cpp index 1adc04ee1b..a35e0237d0 100644 --- a/libraries/animation/src/AnimClip.cpp +++ b/libraries/animation/src/AnimClip.cpp @@ -99,65 +99,64 @@ void AnimClip::copyFromNetworkAnim() { assert(_networkAnim && _networkAnim->isLoaded() && _skeleton); _anim.clear(); - // build a mapping from animation joint indices to skeleton joint indices. + auto avatarSkeleton = getSkeleton(); + + // build a mapping from animation joint indices to avatar joint indices. // by matching joints with the same name. - const HFMModel& hfmModel = _networkAnim->getHFMModel(); - AnimSkeleton animSkeleton(hfmModel); - const auto animJointCount = animSkeleton.getNumJoints(); - const auto skeletonJointCount = _skeleton->getNumJoints(); - std::vector jointMap; - jointMap.reserve(animJointCount); - for (int i = 0; i < animJointCount; i++) { - int skeletonJoint = _skeleton->nameToJointIndex(animSkeleton.getJointName(i)); - jointMap.push_back(skeletonJoint); + const HFMModel& animModel = _networkAnim->getHFMModel(); + AnimSkeleton animSkeleton(animModel); + const int animJointCount = animSkeleton.getNumJoints(); + const int avatarJointCount = avatarSkeleton->getNumJoints(); + std::vector animToAvatarJointIndexMap; + animToAvatarJointIndexMap.reserve(animJointCount); + for (int animJointIndex = 0; animJointIndex < animJointCount; animJointIndex++) { + QString animJointName = animSkeleton.getJointName(animJointIndex); + int avatarJointIndex = avatarSkeleton->nameToJointIndex(animJointName); + animToAvatarJointIndexMap.push_back(avatarJointIndex); } - const int frameCount = hfmModel.animationFrames.size(); - _anim.resize(frameCount); + const int animFrameCount = animModel.animationFrames.size(); + _anim.resize(animFrameCount); - for (int frame = 0; frame < frameCount; frame++) { + for (int frame = 0; frame < animFrameCount; frame++) { - const HFMAnimationFrame& hfmAnimFrame = hfmModel.animationFrames[frame]; + const HFMAnimationFrame& animFrame = animModel.animationFrames[frame]; // init all joints in animation to default pose - // this will give us a resonable result for bones in the model skeleton but not in the animation. - _anim[frame].reserve(skeletonJointCount); - for (int skeletonJoint = 0; skeletonJoint < skeletonJointCount; skeletonJoint++) { - _anim[frame].push_back(_skeleton->getRelativeDefaultPose(skeletonJoint)); + // this will give us a resonable result for bones in the avatar skeleton but not in the animation. + _anim[frame].reserve(avatarJointCount); + for (int avatarJointIndex = 0; avatarJointIndex < avatarJointCount; avatarJointIndex++) { + _anim[frame].push_back(avatarSkeleton->getRelativeDefaultPose(avatarJointIndex)); } - for (int animJoint = 0; animJoint < animJointCount; animJoint++) { - int skeletonJoint = jointMap[animJoint]; + for (int animJointIndex = 0; animJointIndex < animJointCount; animJointIndex++) { + int avatarJointIndex = animToAvatarJointIndexMap[animJointIndex]; - const glm::vec3& hfmAnimTrans = hfmAnimFrame.translations[animJoint]; - const glm::quat& hfmAnimRot = hfmAnimFrame.rotations[animJoint]; + // skip joints that are in the animation but not in the avatar. + if (avatarJointIndex >= 0 && avatarJointIndex < avatarJointCount) { - // skip joints that are in the animation but not in the skeleton. - if (skeletonJoint >= 0 && skeletonJoint < skeletonJointCount) { + const glm::vec3& animTrans = animFrame.translations[animJointIndex]; + const glm::quat& animRot = animFrame.rotations[animJointIndex]; - AnimPose preRot, postRot; - preRot = animSkeleton.getPreRotationPose(animJoint); - postRot = animSkeleton.getPostRotationPose(animJoint); + const AnimPose& animPreRotPose = animSkeleton.getPreRotationPose(animJointIndex); + AnimPose animPostRotPose = animSkeleton.getPostRotationPose(animJointIndex); + AnimPose animRotPose(glm::vec3(1.0f), animRot, glm::vec3()); - // cancel out scale - preRot.scale() = glm::vec3(1.0f); - postRot.scale() = glm::vec3(1.0f); + // adjust anim scale to equal the scale from the avatar joint. + // we do not support animated scale. + const AnimPose& avatarDefaultPose = avatarSkeleton->getRelativeDefaultPose(avatarJointIndex); + animPostRotPose.scale() = avatarDefaultPose.scale(); - AnimPose rot(glm::vec3(1.0f), hfmAnimRot, glm::vec3()); - - // adjust translation offsets, so large translation animatons on the reference skeleton - // will be adjusted when played on a skeleton with short limbs. - const glm::vec3& hfmZeroTrans = hfmModel.animationFrames[0].translations[animJoint]; - const AnimPose& relDefaultPose = _skeleton->getRelativeDefaultPose(skeletonJoint); + // retarget translation from animation to avatar + const glm::vec3& animZeroTrans = animModel.animationFrames[0].translations[animJointIndex]; float boneLengthScale = 1.0f; const float EPSILON = 0.0001f; - if (fabsf(glm::length(hfmZeroTrans)) > EPSILON) { - boneLengthScale = glm::length(relDefaultPose.trans()) / glm::length(hfmZeroTrans); + if (fabsf(glm::length(animZeroTrans)) > EPSILON) { + boneLengthScale = glm::length(avatarDefaultPose.trans()) / glm::length(animZeroTrans); } + AnimPose animTransPose = AnimPose(glm::vec3(1.0f), glm::quat(), avatarDefaultPose.trans() + boneLengthScale * (animTrans - animZeroTrans)); - AnimPose trans = AnimPose(glm::vec3(1.0f), glm::quat(), relDefaultPose.trans() + boneLengthScale * (hfmAnimTrans - hfmZeroTrans)); - - _anim[frame][skeletonJoint] = trans * preRot * rot * postRot; + _anim[frame][avatarJointIndex] = animTransPose * animPreRotPose * animRotPose * animPostRotPose; } } } @@ -165,7 +164,7 @@ void AnimClip::copyFromNetworkAnim() { // mirrorAnim will be re-built on demand, if needed. _mirrorAnim.clear(); - _poses.resize(skeletonJointCount); + _poses.resize(avatarJointCount); } void AnimClip::buildMirrorAnim() { diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index 25f154e9fd..0413210776 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -1878,13 +1878,15 @@ 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) && (ikNode)) { - if (params.secondaryControllerFlags[i] & (uint8_t)ControllerFlags::Enabled) { - ikNode->setSecondaryTargetInRigFrame(index, params.secondaryControllerPoses[i]); - } else { - ikNode->clearSecondaryTarget(index); + if (ikNode) { + for (int i = 0; i < (int)NumSecondaryControllerTypes; i++) { + int index = indexOfJoint(secondaryControllerJointNames[i]); + if (index >= 0) { + if (params.secondaryControllerFlags[i] & (uint8_t)ControllerFlags::Enabled) { + ikNode->setSecondaryTargetInRigFrame(index, params.secondaryControllerPoses[i]); + } else { + ikNode->clearSecondaryTarget(index); + } } } } @@ -2177,4 +2179,4 @@ void Rig::initFlow(bool isActive) { _internalFlow.cleanUp(); _networkFlow.cleanUp(); } -} \ No newline at end of file +}