From c85e187c6174c9894a660b433464519db1e0ccad Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Thu, 13 Jul 2017 18:12:33 -0700 Subject: [PATCH] first stab at secondary target pose support --- interface/src/Application.cpp | 16 ++- interface/src/avatar/MySkeletonModel.cpp | 132 +++++++----------- .../animation/src/AnimInverseKinematics.cpp | 31 ++++ .../animation/src/AnimInverseKinematics.h | 6 + libraries/animation/src/Rig.cpp | 71 ++++++---- libraries/animation/src/Rig.h | 43 ++++-- .../controllers/src/controllers/Actions.h | 14 +- 7 files changed, 190 insertions(+), 123 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 9497456677..37001b55bb 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -4749,7 +4749,7 @@ void Application::update(float deltaTime) { myAvatar->setDriveKey(MyAvatar::ZOOM, userInputMapper->getActionState(controller::Action::TRANSLATE_CAMERA_Z)); } - static std::vector avatarControllerActions = { + static const std::vector avatarControllerActions = { controller::Action::LEFT_HAND, controller::Action::RIGHT_HAND, controller::Action::LEFT_FOOT, @@ -4796,7 +4796,19 @@ void Application::update(float deltaTime) { controller::Action::RIGHT_HAND_PINKY1, controller::Action::RIGHT_HAND_PINKY2, controller::Action::RIGHT_HAND_PINKY3, - controller::Action::RIGHT_HAND_PINKY4 + controller::Action::RIGHT_HAND_PINKY4, + controller::Action::LEFT_ARM, + controller::Action::RIGHT_ARM, + controller::Action::LEFT_SHOULDER, + controller::Action::RIGHT_SHOULDER, + controller::Action::LEFT_FORE_ARM, + controller::Action::RIGHT_FORE_ARM, + controller::Action::LEFT_LEG, + controller::Action::RIGHT_LEG, + controller::Action::LEFT_UP_LEG, + controller::Action::RIGHT_UP_LEG, + controller::Action::LEFT_TOE_BASE, + controller::Action::RIGHT_TOE_BASE }; glm::mat4 myAvatarMatrix = createMatFromQuatAndPos(myAvatar->getOrientation(), myAvatar->getPosition()); diff --git a/interface/src/avatar/MySkeletonModel.cpp b/interface/src/avatar/MySkeletonModel.cpp index f97b20dcca..4a86e0ce0a 100644 --- a/interface/src/avatar/MySkeletonModel.cpp +++ b/interface/src/avatar/MySkeletonModel.cpp @@ -56,96 +56,72 @@ void MySkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) { auto avatarHeadPose = myAvatar->getControllerPoseInAvatarFrame(controller::Action::HEAD); if (avatarHeadPose.isValid()) { AnimPose pose(avatarHeadPose.getRotation(), avatarHeadPose.getTranslation()); - params.controllerPoses[Rig::ControllerType_Head] = avatarToRigPose * pose; - params.controllerActiveFlags[Rig::ControllerType_Head] = true; + params.primaryControllerPoses[Rig::PrimaryControllerType_Head] = avatarToRigPose * pose; + params.primaryControllerActiveFlags[Rig::PrimaryControllerType_Head] = true; } else { // even though full head IK is disabled, the rig still needs the head orientation to rotate the head up and // down in desktop mode. // preMult 180 is necessary to convert from avatar to rig coordinates. // postMult 180 is necessary to convert head from -z forward to z forward. glm::quat headRot = Quaternions::Y_180 * head->getFinalOrientationInLocalFrame() * Quaternions::Y_180; - params.controllerPoses[Rig::ControllerType_Head] = AnimPose(glm::vec3(1.0f), headRot, glm::vec3(0.0f)); - params.controllerActiveFlags[Rig::ControllerType_Head] = false; + params.primaryControllerPoses[Rig::PrimaryControllerType_Head] = AnimPose(glm::vec3(1.0f), headRot, glm::vec3(0.0f)); + params.primaryControllerActiveFlags[Rig::PrimaryControllerType_Head] = false; } - auto avatarHipsPose = myAvatar->getControllerPoseInAvatarFrame(controller::Action::HIPS); - if (avatarHipsPose.isValid()) { - AnimPose pose(avatarHipsPose.getRotation(), avatarHipsPose.getTranslation()); - params.controllerPoses[Rig::ControllerType_Hips] = avatarToRigPose * pose; - params.controllerActiveFlags[Rig::ControllerType_Hips] = true; - } else { - params.controllerPoses[Rig::ControllerType_Hips] = AnimPose::identity; - params.controllerActiveFlags[Rig::ControllerType_Hips] = false; + // + // primary controller poses, control IK targets directly. + // + + static const std::vector> primaryControllers = { + { controller::Action::LEFT_HAND, Rig::PrimaryControllerType_LeftHand }, + { controller::Action::RIGHT_HAND, Rig::PrimaryControllerType_RightHand }, + { controller::Action::HIPS, Rig::PrimaryControllerType_Hips }, + { controller::Action::LEFT_FOOT, Rig::PrimaryControllerType_LeftFoot }, + { controller::Action::RIGHT_FOOT, Rig::PrimaryControllerType_RightFoot }, + { controller::Action::SPINE2, Rig::PrimaryControllerType_Spine2 } + }; + + for (auto pair : primaryControllers) { + auto pose = myAvatar->getControllerPoseInAvatarFrame(pair.first); + if (pose.isValid()) { + AnimPose pose(pose.getRotation(), pose.getTranslation()); + params.primaryControllerPoses[pair.second] = avatarToRigPose * pose; + params.primaryControllerActiveFlags[pair.second] = true; + } else { + params.primaryControllerPoses[pair.second] = AnimPose::identity; + params.primaryControllerActiveFlags[pair.second] = false; + } } - auto avatarSpine2Pose = myAvatar->getControllerPoseInAvatarFrame(controller::Action::SPINE2); - if (avatarSpine2Pose.isValid()) { - AnimPose pose(avatarSpine2Pose.getRotation(), avatarSpine2Pose.getTranslation()); - params.controllerPoses[Rig::ControllerType_Spine2] = avatarToRigPose * pose; - params.controllerActiveFlags[Rig::ControllerType_Spine2] = true; - } else { - params.controllerPoses[Rig::ControllerType_Spine2] = AnimPose::identity; - params.controllerActiveFlags[Rig::ControllerType_Spine2] = false; - } + // + // secondary controller poses, influence the pose of the skeleton indirectly. + // - auto avatarRightArmPose = myAvatar->getControllerPoseInAvatarFrame(controller::Action::RIGHT_ARM); - if (avatarRightArmPose.isValid()) { - AnimPose pose(avatarRightArmPose.getRotation(), avatarRightArmPose.getTranslation()); - params.controllerPoses[Rig::ControllerType_RightArm] = avatarToRigPose * pose; - params.controllerActiveFlags[Rig::ControllerType_RightArm] = true; - } else { - params.controllerPoses[Rig::ControllerType_RightArm] = AnimPose::identity; - params.controllerActiveFlags[Rig::ControllerType_RightArm] = false; - } + static const std::vector> secondaryControllers = { + { controller::Action::LEFT_SHOULDER, Rig::SecondaryControllerType_LeftShoulder }, + { controller::Action::RIGHT_SHOULDER, Rig::SecondaryControllerType_RightShoulder }, + { controller::Action::LEFT_ARM, Rig::SecondaryControllerType_LeftArm }, + { controller::Action::RIGHT_ARM, Rig::SecondaryControllerType_RightArm }, + { controller::Action::LEFT_FORE_ARM, Rig::SecondaryControllerType_LeftForeArm }, + { controller::Action::RIGHT_FORE_ARM, Rig::SecondaryControllerType_RightForeArm }, + { controller::Action::LEFT_UP_LEG, Rig::SecondaryControllerType_LeftUpLeg }, + { controller::Action::RIGHT_UP_LEG, Rig::SecondaryControllerType_RightUpLeg }, + { controller::Action::LEFT_LEG, Rig::SecondaryControllerType_LeftLeg }, + { controller::Action::RIGHT_LEG, Rig::SecondaryControllerType_RightLeg }, + { controller::Action::LEFT_TOE_BASE, Rig::SecondaryControllerType_LeftToeBase }, + { controller::Action::RIGHT_TOE_BASE, Rig::SecondaryControllerType_RightToeBase } + }; - auto avatarLeftArmPose = myAvatar->getControllerPoseInAvatarFrame(controller::Action::LEFT_ARM); - if (avatarLeftArmPose.isValid()) { - AnimPose pose(avatarLeftArmPose.getRotation(), avatarLeftArmPose.getTranslation()); - params.controllerPoses[Rig::ControllerType_LeftArm] = avatarToRigPose * pose; - params.controllerActiveFlags[Rig::ControllerType_LeftArm] = true; - } else { - params.controllerPoses[Rig::ControllerType_LeftArm] = AnimPose::identity; - params.controllerActiveFlags[Rig::ControllerType_LeftArm] = false; - } - - auto avatarLeftHandPose = myAvatar->getControllerPoseInAvatarFrame(controller::Action::LEFT_HAND); - if (avatarLeftHandPose.isValid()) { - AnimPose pose(avatarLeftHandPose.getRotation(), avatarLeftHandPose.getTranslation()); - params.controllerPoses[Rig::ControllerType_LeftHand] = avatarToRigPose * pose; - params.controllerActiveFlags[Rig::ControllerType_LeftHand] = true; - } else { - params.controllerPoses[Rig::ControllerType_LeftHand] = AnimPose::identity; - params.controllerActiveFlags[Rig::ControllerType_LeftHand] = false; - } - - auto avatarRightHandPose = myAvatar->getControllerPoseInAvatarFrame(controller::Action::RIGHT_HAND); - if (avatarRightHandPose.isValid()) { - AnimPose pose(avatarRightHandPose.getRotation(), avatarRightHandPose.getTranslation()); - params.controllerPoses[Rig::ControllerType_RightHand] = avatarToRigPose * pose; - params.controllerActiveFlags[Rig::ControllerType_RightHand] = true; - } else { - params.controllerPoses[Rig::ControllerType_RightHand] = AnimPose::identity; - params.controllerActiveFlags[Rig::ControllerType_RightHand] = false; - } - - auto avatarLeftFootPose = myAvatar->getControllerPoseInAvatarFrame(controller::Action::LEFT_FOOT); - if (avatarLeftFootPose.isValid()) { - AnimPose pose(avatarLeftFootPose.getRotation(), avatarLeftFootPose.getTranslation()); - params.controllerPoses[Rig::ControllerType_LeftFoot] = avatarToRigPose * pose; - params.controllerActiveFlags[Rig::ControllerType_LeftFoot] = true; - } else { - params.controllerPoses[Rig::ControllerType_LeftFoot] = AnimPose::identity; - params.controllerActiveFlags[Rig::ControllerType_LeftFoot] = false; - } - - auto avatarRightFootPose = myAvatar->getControllerPoseInAvatarFrame(controller::Action::RIGHT_FOOT); - if (avatarRightFootPose.isValid()) { - AnimPose pose(avatarRightFootPose.getRotation(), avatarRightFootPose.getTranslation()); - params.controllerPoses[Rig::ControllerType_RightFoot] = avatarToRigPose * pose; - params.controllerActiveFlags[Rig::ControllerType_RightFoot] = true; - } else { - params.controllerPoses[Rig::ControllerType_RightFoot] = AnimPose::identity; - params.controllerActiveFlags[Rig::ControllerType_RightFoot] = false; + for (auto pair : secondaryControllers) { + auto pose = myAvatar->getControllerPoseInAvatarFrame(pair.first); + if (pose.isValid()) { + AnimPose pose(pose.getRotation(), pose.getTranslation()); + params.secondaryControllerPoses[pair.second] = avatarToRigPose * pose; + params.secondaryControllerActiveFlags[pair.second] = true; + } else { + params.secondaryControllerPoses[pair.second] = AnimPose::identity; + params.secondaryControllerActiveFlags[pair.second] = false; + } } params.bodyCapsuleRadius = myAvatar->getCharacterController()->getCapsuleRadius(); diff --git a/libraries/animation/src/AnimInverseKinematics.cpp b/libraries/animation/src/AnimInverseKinematics.cpp index d7076a443e..86ebe5fc91 100644 --- a/libraries/animation/src/AnimInverseKinematics.cpp +++ b/libraries/animation/src/AnimInverseKinematics.cpp @@ -921,6 +921,7 @@ const AnimPoseVec& AnimInverseKinematics::overlay(const AnimVariantMap& animVars { PROFILE_RANGE_EX(simulation_animation, "ik/ccd", 0xffff00ff, 0); preconditionRelativePosesToAvoidLimbLock(context, targets); + setSecondaryTargets(context); solve(context, targets); } @@ -1015,6 +1016,22 @@ void AnimInverseKinematics::clearIKJointLimitHistory() { } } +void AnimInverseKinematics::setSecondaryTargetInRigFrame(int jointIndex, const AnimPose& pose) { + auto iter = _secondaryTargetsInRigFrame.find(jointIndex); + if (iter != _secondaryTargetsInRigFrame.end()) { + iter->second = pose; + } else { + _secondaryTargetsInRigFrame.insert({ jointIndex, pose }); + } +} + +void AnimInverseKinematics::clearSecondaryTarget(int jointIndex) { + auto iter = _secondaryTargetsInRigFrame.find(jointIndex); + if (iter != _secondaryTargetsInRigFrame.end()) { + _secondaryTargetsInRigFrame.erase(iter); + } +} + RotationConstraint* AnimInverseKinematics::getConstraint(int index) const { RotationConstraint* constraint = nullptr; std::map::const_iterator constraintItr = _constraints.find(index); @@ -1722,6 +1739,20 @@ void AnimInverseKinematics::preconditionRelativePosesToAvoidLimbLock(const AnimC } } +// overwrites _relativePoses with secondary poses. +void AnimInverseKinematics::setSecondaryTargets(const AnimContext& context) { + AnimPose rigToGeometryPose = AnimPose(glm::inverse(context.getGeometryToRigMatrix())); + for (auto& iter : _secondaryTargetsInRigFrame) { + AnimPose absPose = rigToGeometryPose * iter.second; + AnimPose parentAbsPose; + int parentIndex = _skeleton->getParentIndex(iter.first); + if (parentIndex >= 0) { + parentAbsPose = _skeleton->getAbsolutePose(parentIndex, _relativePoses); + } + _relativePoses[iter.first] = parentAbsPose.inverse() * absPose; + } +} + void AnimInverseKinematics::initRelativePosesFromSolutionSource(SolutionSource solutionSource, const AnimPoseVec& underPoses) { const float RELAX_BLEND_FACTOR = (1.0f / 16.0f); const float COPY_BLEND_FACTOR = 1.0f; diff --git a/libraries/animation/src/AnimInverseKinematics.h b/libraries/animation/src/AnimInverseKinematics.h index d473ae3698..2ca333323a 100644 --- a/libraries/animation/src/AnimInverseKinematics.h +++ b/libraries/animation/src/AnimInverseKinematics.h @@ -63,6 +63,9 @@ public: NumSolutionSources, }; + void setSecondaryTargetInRigFrame(int jointIndex, const AnimPose& pose); + void clearSecondaryTarget(int jointIndex); + void setSolutionSource(SolutionSource solutionSource) { _solutionSource = solutionSource; } void setSolutionSourceVar(const QString& solutionSourceVar) { _solutionSourceVar = solutionSourceVar; } @@ -83,6 +86,7 @@ protected: void initRelativePosesFromSolutionSource(SolutionSource solutionSource, const AnimPoseVec& underPose); void blendToPoses(const AnimPoseVec& targetPoses, const AnimPoseVec& underPose, float blendFactor); void preconditionRelativePosesToAvoidLimbLock(const AnimContext& context, const std::vector& targets); + void setSecondaryTargets(const AnimContext& context); // used to pre-compute information about each joint influeced by a spline IK target. struct SplineJointInfo { @@ -136,6 +140,8 @@ protected: AnimPoseVec _relativePoses; // current relative poses AnimPoseVec _limitCenterPoses; // relative + std::map _secondaryTargetsInRigFrame; + std::map> _splineJointInfoMap; // experimental data for moving hips during IK diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index 6ebb68773f..9db8b187b6 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -1474,24 +1474,25 @@ void Rig::updateFromControllerParameters(const ControllerParameters& params, flo _animVars.set("isTalking", params.isTalking); _animVars.set("notIsTalking", !params.isTalking); - bool headEnabled = params.controllerActiveFlags[ControllerType_Head]; - bool leftHandEnabled = params.controllerActiveFlags[ControllerType_LeftHand]; - bool rightHandEnabled = params.controllerActiveFlags[ControllerType_RightHand]; - bool hipsEnabled = params.controllerActiveFlags[ControllerType_Hips]; - bool leftFootEnabled = params.controllerActiveFlags[ControllerType_LeftFoot]; - bool rightFootEnabled = params.controllerActiveFlags[ControllerType_RightFoot]; - bool leftArmEnabled = params.controllerActiveFlags[ControllerType_LeftArm]; - bool rightArmEnabled = params.controllerActiveFlags[ControllerType_RightArm]; - bool spine2Enabled = params.controllerActiveFlags[ControllerType_Spine2]; + bool headEnabled = params.primaryControllerActiveFlags[PrimaryControllerType_Head]; + bool leftHandEnabled = params.primaryControllerActiveFlags[PrimaryControllerType_LeftHand]; + bool rightHandEnabled = params.primaryControllerActiveFlags[PrimaryControllerType_RightHand]; + bool hipsEnabled = params.primaryControllerActiveFlags[PrimaryControllerType_Hips]; + bool leftFootEnabled = params.primaryControllerActiveFlags[PrimaryControllerType_LeftFoot]; + bool rightFootEnabled = params.primaryControllerActiveFlags[PrimaryControllerType_RightFoot]; + bool spine2Enabled = params.primaryControllerActiveFlags[PrimaryControllerType_Spine2]; - updateHead(headEnabled, hipsEnabled, params.controllerPoses[ControllerType_Head]); + bool leftArmEnabled = params.secondaryControllerActiveFlags[SecondaryControllerType_LeftArm]; + bool rightArmEnabled = params.secondaryControllerActiveFlags[SecondaryControllerType_RightArm]; + + updateHead(headEnabled, hipsEnabled, params.primaryControllerPoses[PrimaryControllerType_Head]); updateHands(leftHandEnabled, rightHandEnabled, hipsEnabled, leftArmEnabled, rightArmEnabled, dt, - params.controllerPoses[ControllerType_LeftHand], params.controllerPoses[ControllerType_RightHand], + params.primaryControllerPoses[PrimaryControllerType_LeftHand], params.primaryControllerPoses[PrimaryControllerType_RightHand], params.bodyCapsuleRadius, params.bodyCapsuleHalfHeight, params.bodyCapsuleLocalOffset); updateFeet(leftFootEnabled, rightFootEnabled, - params.controllerPoses[ControllerType_LeftFoot], params.controllerPoses[ControllerType_RightFoot]); + params.primaryControllerPoses[PrimaryControllerType_LeftFoot], params.primaryControllerPoses[PrimaryControllerType_RightFoot]); // if the hips or the feet are being controlled. if (hipsEnabled || rightFootEnabled || leftFootEnabled) { @@ -1512,34 +1513,46 @@ void Rig::updateFromControllerParameters(const ControllerParameters& params, flo if (hipsEnabled) { _animVars.set("hipsType", (int)IKTarget::Type::RotationAndPosition); - _animVars.set("hipsPosition", params.controllerPoses[ControllerType_Hips].trans()); - _animVars.set("hipsRotation", params.controllerPoses[ControllerType_Hips].rot()); + _animVars.set("hipsPosition", params.primaryControllerPoses[PrimaryControllerType_Hips].trans()); + _animVars.set("hipsRotation", params.primaryControllerPoses[PrimaryControllerType_Hips].rot()); } else { _animVars.set("hipsType", (int)IKTarget::Type::Unknown); } if (hipsEnabled && spine2Enabled) { _animVars.set("spine2Type", (int)IKTarget::Type::Spline); - _animVars.set("spine2Position", params.controllerPoses[ControllerType_Spine2].trans()); - _animVars.set("spine2Rotation", params.controllerPoses[ControllerType_Spine2].rot()); + _animVars.set("spine2Position", params.primaryControllerPoses[PrimaryControllerType_Spine2].trans()); + _animVars.set("spine2Rotation", params.primaryControllerPoses[PrimaryControllerType_Spine2].rot()); } else { _animVars.set("spine2Type", (int)IKTarget::Type::Unknown); } - if (leftArmEnabled) { - _animVars.set("leftArmType", (int)IKTarget::Type::RotationAndPosition); - _animVars.set("leftArmPosition", params.controllerPoses[ControllerType_LeftArm].trans()); - _animVars.set("leftArmRotation", params.controllerPoses[ControllerType_LeftArm].rot()); - } else { - _animVars.set("leftArmType", (int)IKTarget::Type::Unknown); - } + // set secondary targets + static const std::vector secondaryControllerJointNames = { + "LeftShoulder", + "RightShoulder", + "LeftArm", + "RightArm", + "LeftForeArm", + "RightForeArm", + "LeftUpLeg", + "RightUpLeg", + "LeftLeg", + "RightLeg", + "LeftToeBase", + "RightToeBase" + }; - if (rightArmEnabled) { - _animVars.set("rightArmType", (int)IKTarget::Type::RotationAndPosition); - _animVars.set("rightArmPosition", params.controllerPoses[ControllerType_RightArm].trans()); - _animVars.set("rightArmRotation", params.controllerPoses[ControllerType_RightArm].rot()); - } else { - _animVars.set("rightArmType", (int)IKTarget::Type::Unknown); + std::shared_ptr ikNode = getAnimInverseKinematicsNode(); + for (int i = 0; i < (int)NumSecondaryControllerTypes; i++) { + int index = indexOfJoint(secondaryControllerJointNames[i]); + if (index >= 0) { + if (params.secondaryControllerActiveFlags[i]) { + ikNode->setSecondaryTargetInRigFrame(index, params.secondaryControllerPoses[i]); + } else { + ikNode->clearSecondaryTarget(index); + } + } } } diff --git a/libraries/animation/src/Rig.h b/libraries/animation/src/Rig.h index c17a7b9c8f..5718c62c26 100644 --- a/libraries/animation/src/Rig.h +++ b/libraries/animation/src/Rig.h @@ -41,22 +41,39 @@ public: bool useNames; }; - enum ControllerType { - ControllerType_Head = 0, - ControllerType_LeftHand, - ControllerType_RightHand, - ControllerType_Hips, - ControllerType_LeftFoot, - ControllerType_RightFoot, - ControllerType_LeftArm, - ControllerType_RightArm, - ControllerType_Spine2, - NumControllerTypes + enum PrimaryControllerType { + PrimaryControllerType_Head = 0, + PrimaryControllerType_LeftHand, + PrimaryControllerType_RightHand, + PrimaryControllerType_Hips, + PrimaryControllerType_LeftFoot, + PrimaryControllerType_RightFoot, + PrimaryControllerType_Spine2, + NumPrimaryControllerTypes + }; + + // NOTE: These should ordered such that joint parents appear before their children. + enum SecondaryControllerType { + SecondaryControllerType_LeftShoulder = 0, + SecondaryControllerType_RightShoulder, + SecondaryControllerType_LeftArm, + SecondaryControllerType_RightArm, + SecondaryControllerType_LeftForeArm, + SecondaryControllerType_RightForeArm, + SecondaryControllerType_LeftUpLeg, + SecondaryControllerType_RightUpLeg, + SecondaryControllerType_LeftLeg, + SecondaryControllerType_RightLeg, + SecondaryControllerType_LeftToeBase, + SecondaryControllerType_RightToeBase, + NumSecondaryControllerTypes }; struct ControllerParameters { - AnimPose controllerPoses[NumControllerTypes]; // rig space - bool controllerActiveFlags[NumControllerTypes]; + AnimPose primaryControllerPoses[NumPrimaryControllerTypes]; // rig space + bool primaryControllerActiveFlags[NumPrimaryControllerTypes]; + AnimPose secondaryControllerPoses[NumSecondaryControllerTypes]; // rig space + bool secondaryControllerActiveFlags[NumSecondaryControllerTypes]; bool isTalking; float bodyCapsuleRadius; float bodyCapsuleHalfHeight; diff --git a/libraries/controllers/src/controllers/Actions.h b/libraries/controllers/src/controllers/Actions.h index ec4800c9aa..9aa9bbdb29 100644 --- a/libraries/controllers/src/controllers/Actions.h +++ b/libraries/controllers/src/controllers/Actions.h @@ -101,6 +101,7 @@ enum class Action { // Bisected aliases for TRANSLATE_CAMERA_Z BOOM_IN, BOOM_OUT, + LEFT_ARM, RIGHT_ARM, @@ -146,7 +147,18 @@ enum class Action { RIGHT_HAND_PINKY3, RIGHT_HAND_PINKY4, - NUM_ACTIONS, + LEFT_SHOULDER, + RIGHT_SHOULDER, + LEFT_FORE_ARM, + RIGHT_FORE_ARM, + LEFT_LEG, + RIGHT_LEG, + LEFT_UP_LEG, + RIGHT_UP_LEG, + LEFT_TOE_BASE, + RIGHT_TOE_BASE, + + NUM_ACTIONS }; template